0

I have some legacy code which we are seeing some issues. For example, if we have,

var dt2030 = new DateTime(2030, 01, 01);
var dt1 = Convert.ToDateTime(dt2030.ToString("dd/MM/yy"));

The dt1 here denotes 1930. Is there any fixed format for yy? I mean if it is 10 years different from current then take older else take a newer year?

enter image description here

Imran Qadir Baksh - Baloch
  • 32,612
  • 68
  • 179
  • 322
  • 1
    ToString should probably be `ToString("dd/MM/yyyy")`. See formats [here](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings). – Cicero Jun 14 '20 at 08:13
  • 1
    I can't reproduce it, get back 2030. Did you check your OS date and time settings? – Pavel Anikhouski Jun 14 '20 at 08:15
  • 3
    @user960567 Please refer to the remarks section of [`TwoDigitYearMax`](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.gregoriancalendar.twodigityearmax?view=netcore-3.1#remarks) property. _The initial value of this property is derived from the settings in the regional and language options portion of Control Panel_ So, as I already told you, you should check your regional settings – Pavel Anikhouski Jun 14 '20 at 08:33
  • Can you talk us through why you have a date which you then convert to a string and **back to a date**? – mjwills Jun 14 '20 at 11:09
  • @mjwills, it's all about the legacy code which recently found that some developer doing this. My current challenge is MRZ which just have 2 digits for year https://en.wikipedia.org/wiki/Machine-readable_passport – Imran Qadir Baksh - Baloch Jun 14 '20 at 11:21
  • Fundamentally, if you store a 4 digit number in a 2 digit number then you are bound to have issues. ;) – mjwills Jun 14 '20 at 13:28
  • This sample code may not be reproducible depending on the OS and the calendar settings, see https://stackoverflow.com/questions/58508724/parsing-12-25-35-to-a-date-using-invariantculture-2-digit-year – manuc66 Jun 17 '22 at 11:49

2 Answers2

3

The default calendar goes from 1930 to 2029, hence if you ask it to parse a date of the year 30 it can't be anything else than 1930, by default.

A possible solution is to use CultureInfo and expand the range, then when parsing the date also passing the CultureInfo as parameter, in:

    CultureInfo ci = new CultureInfo(CultureInfo.CurrentCulture.LCID);
    ci.Calendar.TwoDigitYearMax = 2099;

    var dt2030 = new DateTime(2030, 01, 01);
    var dt1 = Convert.ToDateTime(dt2030.ToString("dd/MM/yy"), ci);

    Console.WriteLine(dt1);
Balastrong
  • 4,336
  • 2
  • 12
  • 31
3

The issue in your code is yy. You have to use yyyy. You should use the correct format yyyy.

var dt2030 = new DateTime(2030, 01, 01);
var dt1 = Convert.ToDateTime(dt2030.ToString("dd/MM/yyyy"));
Console.WriteLine(dt1);
Mei
  • 305
  • 2
  • 7