Преобразовать год из двух цифр в год из четырех цифр - PullRequest
28 голосов
/ 08 января 2010

Это вопрос лучших практик. У меня есть утилита, которая принимает двухзначный год в виде строки, и мне нужно преобразовать ее в четырехзначный год в виде строки. сейчас я делаю

//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);

Я уверен, что делаю это ужасно неправильно, какие-нибудь указатели?

Ответы [ 16 ]

60 голосов
/ 02 мая 2012

.NET Framework имеет метод, который делает именно то, что вы хотите:

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

Таким образом, вы будете правильно придерживаться текущих региональных настроек, определенных в панели управления (или групповой политике):

Regional settings

16 голосов
/ 08 января 2010

Учитывая, что в настоящее время есть живые люди, родившиеся до 1950 года, но никто не родился после 2010 года, ваше использование 50 в качестве точки переворота кажется нарушенным.

Что касается даты рождения, не можете ли вы установить точку перегиба на «год сейчас» (т. Е. 10) в своем приложении? Даже тогда у вас будут проблемы с теми, кто родился до 1911 года ...

Нет идеального способа сделать это - вы создаете информацию из воздуха.

Я предположил, что DOB = дата рождения. Для других данных (скажем, срок погашения финансового инструмента) выбор может быть другим, но столь же несовершенным.

7 голосов
/ 08 января 2010

После того, как вы приняли другие предложения относительно того, когда нужно перевернуть свои вековые предположения с 19 на 20, лучший из всех возможных миров включает обновление источника данных раз и навсегда с помощью четырехзначных лет, чтобы вы могли прекратить делать предположения все время.

6 голосов
/ 08 января 2010

Вы также можете использовать метод DateTime.TryParse для преобразования вашей даты. Он использует текущие настройки культуры для определения сводного года (в моем случае это 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);

Вывод:

CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax: 2029

Дата создания с годом = 28 - 01/01/2028 00: 00: 00

Дата создания с годом = 29 - 01/02/2029 00: 00: 00

Дата создания с годом = 30 - 01/03/1930 00: 00: 00

Если вы хотите изменить поведение, которое вы можете создать культуру с годом вы хотите использовать в качестве опоры. В этой теме показан пример

Элемент управления DateTime.TryParse века C #

Но, как сказал Мартин, если вы хотите управлять периодом времени, который охватывает более 100 лет, нет способа сделать это только с двумя цифрами.

5 голосов
/ 15 октября 2013

Реализация

System.Globalization.CultureInfo.CurrentCulture.Calendar.ToFourDigitYear 

есть

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;
}

Надеюсь, это поможет!

5 голосов
/ 08 января 2010

Я думаю, что Java имеет хорошую реализацию этого:

http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html#year

Люди редко указывают годы в будущем, используя двузначный код. Реализация Java справляется с этим, предполагая, что диапазон отстает на 80 лет и на 20 лет больше, чем в текущем году. Поэтому сейчас 30 будет 2030, а 31 - 1931. Кроме того, эта реализация является гибкой, изменяя ее диапазоны с течением времени, чтобы вам не приходилось менять код каждые десять лет или около того.

Я только что протестировал, и Excel также использует те же правила для преобразования двухзначного года. 1/1/29 превращается в 01.01.2029. 1/1/30 превращается в 1/1/1930.

4 голосов
/ 08 января 2010

Может быть разумнее проверить tmpYear> currentYear% 100. Если это так, то это 19XX, в противном случае 20XX.

0 голосов
/ 28 сентября 2018

Этот метод может преобразовать последние двухлетние цифры кредитной карты в четыре года


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 голосов
/ 20 апреля 2018

Мои два цента,

Учитывая возрастной диапазон = [18, 100+], двухзначный год = 90, я могу сделать

current year - twoDigitsYear = 2018 - 90 = 1928, я получил 19, 28

следовательно, 19 - это первые две цифры года рождения, а 28 - это возраст, который
год = 1990, возраст = 28

Но это не будет работать, когда возраст 0 и 100 включены в диапазон, то же самое с некоторыми другими ответами здесь.

0 голосов
/ 13 июня 2017

Это решение, которое мы используем для дат истечения срока действия, пользователь вводит MM и YY в отдельные поля. Это приводит к тому, что даты будут 31-го или 30-го и 28-го или 29-го числа также для февраля.

/// <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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...