web-dev-qa-db-fra.com

Convertir une année à deux chiffres en une année à quatre chiffres

C'est une question de bonnes pratiques. J'ai un utilitaire qui prend une année à deux chiffres en tant que chaîne et je dois le convertir en une année à quatre chiffres en tant que chaîne. maintenant je fais 

//DOB's format is "MMM (D)D YY" that first digit of the day is not there for numbers 1-9
string tmpYear = rowIn.DOB.Substring(rowIn.DOB.Length - 3, 2); //-3 because it is 0 indexed
if (Convert.ToInt16(tmpYear) > 50)
    tmpYear = String.Format("19{0}", tmpYear);
else
    tmpYear = String.Format("20{0}", tmpYear);

Je suis sûr que je le fais horriblement mal, des pointeurs?

27
Scott Chamberlain

Le framework .NET a une méthode qui fait exactement ce que vous voulez:

int fourDigitYear = CultureInfo.CurrentCulture.Calendar.ToFourDigitYear(twoDigitYear)

Ainsi, vous respecterez correctement les paramètres régionaux actuels définis dans le Panneau de configuration (ou la stratégie de groupe):

Regional settings

58
Vedran

Étant donné qu'il y a des personnes en vie nées avant 1950, mais aucune née après 2010, votre utilisation de 50 comme point de retournement semble rompue.

Pour la date de naissance, ne pouvez-vous pas définir le point de retournement sur "l'année actuelle" (c'est-à-dire 10) dans votre application? Même dans ce cas, vous aurez des problèmes avec ceux nés avant 1911 ...

Il n'y a pas de moyen idéal pour cela: vous créez des informations à partir de rien.

J'ai supposé DOB = date de naissance. Pour d'autres données (par exemple, la maturité d'un instrument financier), le choix peut être différent, mais tout aussi imparfait.

16
martin clayton

Une fois que vous avez pris d'autres suggestions sur le moment de basculer vos hypothèses de siècle de 19 à 20 ans, le meilleur des mondes possibles consiste à mettre à jour votre source de données une fois pour toutes avec des années à 4 chiffres, de sorte que vous puissiez cesser de temps.

7
Joel Mueller

Vous pouvez également utiliser la méthode DateTime.TryParse pour convertir votre date. Il utilise les paramètres de culture actuels pour définir l'année pivot (dans mon cas, il s'agit de 2029)

DateTime resultDate;
Console.WriteLine("CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax : {0}", System.Globalization.CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax);
DateTime.TryParse("01/01/28", out resultDate);
Console.WriteLine("Generated date with year=28 - {0}",resultDate);
DateTime.TryParse("01/02/29",out resultDate);
Console.WriteLine("Generated date with year=29 - {0}", resultDate);
DateTime.TryParse("01/03/30", out resultDate);
Console.WriteLine("Generated date with year=30 - {0}", resultDate);

La sortie est:

CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax: 2029

Date générée avec l'année = 28 - 01/01/2028 00:00:00

Date générée avec l'année = 29 - 01/02/2029 00:00:00

Date générée avec l'année = 30 - 01/03/1930 00:00:00

Si vous souhaitez modifier le comportement, vous pouvez créer une culture avec l'année que vous souhaitez utiliser comme pivot. Ce fil montre un exemple

DateTime.TryParse century control C #

Mais comme l'a déclaré martin, si vous voulez gérer une période de plus de 100 ans, il n'y a aucun moyen de le faire avec seulement 2 chiffres.

6
FrenchData

Je pense que Java a une bonne implémentation de ceci:

http://Java.Sun.com/javase/6/docs/api/Java/text/SimpleDateFormat.html#year

Les gens spécifient rarement des années loin dans le futur en utilisant un code à deux chiffres. L'implémentation Java gère cela en supposant un intervalle de 80 ans avec 20 ans d'avance sur l'année en cours. En ce moment, 30 correspondrait à 2030, tandis que 31 correspondrait à 1931. De plus, cette implémentation est flexible et modifie ses plages au fil du temps, de sorte que vous ne devez pas modifier le code toutes les dix années environ.

Je viens de tester, et Excel utilise également ces mêmes règles pour la conversion d'année à 2 chiffres. 1/1/29 devient 1/1/2029. 1/1/30 se transforme en 1/1/1930.

5
jdmichal

L'implémentation de 

System.Globalization.CultureInfo.CurrentCulture.Calendar.ToFourDigitYear 

est

public virtual int ToFourDigitYear(int year)
{
  if (year < 0)
    throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  if (year < 100)
    return (this.TwoDigitYearMax / 100 - (year > this.TwoDigitYearMax % 100 ? 1 : 0)) * 100 + year;
  else
    return year;
}

J'espère que cela t'aides!

5
KManohar

Il pourrait être plus intelligent de vérifier tmpYear> currentYear% 100. Si c'est le cas, alors c'est 19XX, sinon 20XX.

4
Ponkadoodle

Avait un problème similaire, et est venu avec ça ... HTH!

value = this.GetDate()

if (value.Length >= 6)//ensure that the date is mmddyy
{
    int year = 0;

    if (int.TryParse(value.Substring(4, 2), out year))
    {
        int pastMillenium = int.Parse(DateTime.Now.ToString("yyyy").Substring(0, 2)) - 1;

        if (year > int.Parse(DateTime.Now.ToString("yy")))//if its a future year it's most likely 19XX
        {
            value = string.Format("{0}{1}{2}", value.Substring(0, 4), pastMillenium, year.ToString().PadLeft(2, '0'));
        }
        else
        {
            value = string.Format("{0}{1}{2}", value.Substring(0, 4), pastMillenium + 1, year.ToString().PadLeft(2, '0'));
        }
    }
    else
    {
        value = string.Empty;
    }
}
else
{
    value = string.Empty;
}
0
bizah

Si vous calculez pour une personne, il n'aura probablement pas plus de 100 ans ...

Ex: 751212

var nr = "751212";
var century = DateTime.Now.AddYears(-100).Year.ToString().Substring(0, 2);

var days = (DateTime.Now - DateTime.Parse(century + nr)).Days;
decimal years = days / 365.25m;
if(years>=99)
 century = DateTime.Now.Year.ToString().Substring(0, 2);

var fullnr = century+nr;
0
Mattias Engman

Ma réponse ne correspond pas à votre question mais pour les cartes de crédit, j'ajoute simplement 2 chiffres de l'année en cours.

    private int UpconvertTwoDigitYearToFour(int yearTwoOrFour)
    {
        try
        {
            if (yearTwoOrFour.ToString().Length <= 2)
            {
                DateTime yearOnly = DateTime.ParseExact(yearTwoOrFour.ToString("D2"), "yy", null);
                return yearOnly.Year;
            }
        }
        catch
        {
        }

        return yearTwoOrFour;
    }
0
Pawel Cioch

Pour changer une année à 2 chiffres en 4 chiffres actuels ou antérieurs -

year = year + (DateTime.Today.Year - DateTime.Today.Year%100);
if (year > DateTime.Today.Year)
                year = year - 100;
0
Ellen22

Essayez ce code simple 

// Invoque la méthode TextBoxDateFormat avec la date comme paramètre.

Méthode

public void TextBoxDateFormat(string str1)

{

// Takes the current date format if MM/DD/YY or MM/DD/YYYY

DateTime dt = Convert.ToDateTime(str1);

//Converts the requested date into MM/DD/YYYY and assign it to textbox field

TextBox = String.Format("{0:MM/dd/yyyy}", dt.ToShortDateString());


//include your validation code if required

}
0
Jags

Cette solution que nous utilisons pour les dates d'expiration, l'utilisateur entre MM et AA dans des champs distincts. Les dates sont donc les 31, 30, 28 et 29 février.

/// <summary>
/// Creates datetime for current century and sets days to end of month
/// </summary>
/// <param name="MM"></param>
/// <param name="YY"></param>
/// <returns></returns>
public static DateTime GetEndOfMonth(string MM, string YY)
{
    // YY -> YYYY #RipVanWinkle
    // Gets Current century and adds YY to it.
    // Minus 5 to allow dates that may be expired to be entered.
    // eg. today is 2017, 12 = 2012 and 11 = 2111
    int currentYear = DateTime.Now.Year;
    string thisYear = currentYear.ToString().Substring(0, 2) + YY;
    int month = Int32.Parse(MM);
    int year = Int32.Parse(thisYear);
    if ((currentYear - 5) > year)
        year += 100;

    return new DateTime(year, month, DateTime.DaysInMonth(year, month));
}
0
tyler_mitchell

Cette méthode permet de convertir la carte de crédit en chiffres des deux dernières années en quatre ans. 


private static int ToFourDigitYear(int year)
{
    string stringYear = year.ToString("00");
    if (stringYear.Length == 2)
    {
        int currentYear = DateTime.Now.Year;
        string firstTwoDigitsOfCurrentYear = currentYear.ToString().Substring(0, 2);
        year = Convert.ToInt32(firstTwoDigitsOfCurrentYear + stringYear);
        if (year < currentYear)
            year = year + 100;
    }
    return year;
}
0
Shiv

Mes deux centimes, 

Étant donné une tranche d’âge = [18, 100+], année à deux chiffres = 90, je peux faire 

current year - twoDigitsYear = 2018 - 90 = 1928, j'ai 19, 28

19 est donc les deux premiers chiffres de l’année de naissance, et 28 l’âge, qui est
année = 1990, âge = 28

Mais cela ne fonctionnera pas si les âges 0 et 100 sont tous les deux inclus dans la plage, comme pour certaines des autres réponses ici.

0
Beeing Jk

Par curiosité, d'où obtenez-vous ces données? À partir d'un formulaire? Dans ce cas; Je demanderais simplement à l'utilisateur de renseigner (ou de sélectionner, d'une manière ou d'une autre) l'année à quatre chiffres ou d'obtenir son âge et son mois/jour de naissance, et d'utiliser ces données pour déterminer son année de naissance. De cette façon, vous n’auriez pas à vous soucier de ce problème :)

Edit: Utilisez DateTime pour utiliser ce type de données.

0
Leif