Date converter, looking for good and easy way

Noah Aas 605 Reputation points
2025-02-05T15:49:20.82+00:00

Hello,

I need to display a date in a different format. How can I achieve this easily? How do I go about it? Thanks for tips in advance.

The algorithm

Variant 1

//Month:  1=January, 2=February, 9=September, …, A=October, B=November
//Day:    standard from 01 to 31
//Year:   A=2017, B=2018, C=2019, … D=2020, E=2021, F=2022, G=2023, H=2024 , I= 2025
//Month:  A=January, B=February, …
//Day:    1=1st, 2=2nd, 9=9th, … 0=10th, A=11th, B=12th,…
  • IB5
  • IBA

Variant 2

//Year:   1=2017, … , 5=2021, 6=2022, ....9=2025, A=2026, B=2027
//Month:  1=January, 2=February, 9=September, …, A=October; B=November; C=December
//Day:    standard from 01 to 31
  • 05.02.2025 --> 9205 (two digits for day) Year, Month, Day
  • 05.02.2025 --> 925 (one or two digits for day)
  • 11.02.2025 --> 9211 (one or two digits for day)
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,285 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Michael Taylor 56,861 Reputation points
    2025-02-05T20:26:15.0133333+00:00

    I would create a custom ICustomFormatter to allow you to convert the datetime values. Then you can use it with any of the standard formatting methods available in NET.

    Here's a simple example that seems to work for your 2 specific cases. Note that it relies on C# switch expressions. If you're using an older version of C# then you'll need to replace that with something equivalent like if statements.

    public class VariantCustomFormatter : IFormatProvider, ICustomFormatter
    {
        public string Format ( string? format, object? arg, IFormatProvider? formatProvider )
        {
            if (arg is DateTime dt)
            {
                switch (String.IsNullOrEmpty(format) ? default(char) : format[0])
                {
                    case 'V': return HandleVariant1(dt);
                    case 'v': return HandleVariant2(dt);
    
                    default: return HandleOtherFormats(format, arg);
                };
            };
    
            return HandleOtherFormats (format, arg);
        }
    
        public object? GetFormat ( Type? formatType )
        {
            if (formatType == typeof(ICustomFormatter))
                return this;
    
            return null;
        }
    
        private static string HandleVariant1 ( DateTime dt )
        {
            //YMD
            //Month = A + (Month - 1)
            //Day = 1-90A-...
            //Year = A + (Year - 2017)
    
            var yearCode = ((char)('A' + (dt.Year - 2017))).ToString();
            var monthCode = ((char)('A' + (dt.Month - 1))).ToString();
    
            //Using switch expression, if not supported then use IF
            var dayCode = dt.Day switch {
                < 10 => dt.Day.ToString(),
                > 10 => (dt.Day - 1).ToString("X"),
                _ => "0",
            };
            
            return yearCode + monthCode + dayCode;
        }
    
        private static string HandleVariant2 ( DateTime dt )
        {
            //YMDD
            //Month = 1-9A-C
            //Day = 1-31
            //Year = -2025 = 1..9, 2026+ = A+
    
            //Using switch expression, if not supported then use IF
            var yearCode = dt.Year switch {
                > 2025 => ((char)('A' + (dt.Year - 2026))).ToString(),
                _ => (dt.Year - 2016).ToString(),
            };
            var monthCode = dt.Month switch {
                <= 9 => dt.Month.ToString(),
                _ => ((char)('A' + (dt.Month - 1))).ToString(),
            };
            var dayCode = dt.Day.ToString("00");
    
            return yearCode + monthCode + dayCode;
        }
    
        private static string HandleOtherFormats ( string format, object arg )
        {
            if (arg is IFormattable)
                return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
    
            return arg?.ToString() ?? "";
        }
    }
    

    This code is not optimized. You'll need to make it production ready. Usage example.

    var items = new [] {
        DateTime.Parse("02/05/2025"),
        DateTime.Parse("02/11/2025"),    
    };
    
    foreach (var item in items)
    {
        var formatProvider = new VariantCustomFormatter();
    
        Console.WriteLine(String.Format(formatProvider, "{0:V}", item));
        Console.WriteLine(String.Format(formatProvider, "{0:v}", item));
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.