Преобразование двухзначного года в четырехзначный год
Это вопрос лучших практик. У меня есть утилита, которая принимает двухзначный год в виде строки, и мне нужно преобразовать ее в четырехзначный год в виде строки. сейчас я делаю
//DOB 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);
Я уверен, что делаю это ужасно неправильно, любые указатели?
Ответы
Ответ 1
В .NET Framework есть метод, который делает именно то, что вы хотите:
int fourDigitYear = CultureInfo.CurrentCulture.Calendar.ToFourDigitYear(twoDigitYear)
Таким образом, вы будете правильно придерживаться текущих региональных настроек, определенных в панели управления (или групповой политики):
![Regional settings]()
Ответ 2
Учитывая, что есть люди, живущие сейчас, родившиеся до 1950 года, но ни один из них не родился после 2010 года, ваше использование 50 в качестве перевернутой точки кажется сломанным.
На дату рождения вы не можете установить точку перехода в "год года" (т.е. 10) в вашем приложении? Даже тогда у вас будут проблемы с родившимися до 1911 года...
Нет идеального способа сделать это - вы создаете информацию из воздуха.
Я предположил DOB = дата рождения. Для других данных (например, зрелости финансового инструмента) выбор может быть другим, но также несовершенным.
Ответ 3
После того, как вы приняли другие предложения относительно того, когда нужно перевернуть свои предположения века от 19 до 20, лучший из всех возможных миров включает в себя обновление вашего источника данных раз и навсегда с 4-значными годами, поэтому вы можете прекратить допущения все время.
Ответ 4
Вы также можете использовать метод 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 century control С#
Но, как сказал Мартин, если вы хотите управлять периодом времени, который охватывает более 100 лет, нет возможности сделать это всего за 2 цифры.
Ответ 5
Я думаю, что 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 превращается в 1/1/2029. 1/1/30 превращается в 1/1/1930.
Ответ 6
Реализация
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;
}
Надеюсь, это поможет!
Ответ 7
Возможно, было бы разумнее проверить tmpYear > currentYear% 100. Если это так, то это 19XX, иначе 20XX.
Ответ 8
Из любопытства, откуда вы получаете эти данные? Из формы? В таком случае; Я просто попрошу пользователя заполнить (или как-нибудь выбрать) год четырьмя цифрами или получить возраст пользователей и месяц/день рождения и использовать эти данные, чтобы выяснить, в каком году они родились. Таким образом, вам не придется беспокоиться об этой проблеме вообще:)
Изменить: Используйте DateTime для работы с такими типами данных.
Ответ 9
Попробуйте этот простой код
//Вызов метода TextBoxDateFormat с параметром даты в качестве параметра.
Метод
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
}
Ответ 10
Имел подобную проблему, и придумал это... 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 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;
}
Ответ 11
Мой ответ не будет соответствовать вашему вопросу, но для кредитных карт я просто добавляю 2 цифры текущего года.
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;
}
Ответ 12
Если вы рассчитываете для человека, он, вероятно, не будет более 100 лет...
Например: 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;
Ответ 13
Чтобы изменить 2-значный год на 4-значный ток или раньше -
year = year + (DateTime.Today.Year - DateTime.Today.Year%100);
if (year > DateTime.Today.Year)
year = year - 100;
Ответ 14
Это решение, которое мы используем для дат истечения срока действия, вводит 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));
}