Converting a year from 4 digit to 2 digit and back again in C#

Viewed 176019

My credit card processor requires I send a two-digit year from the credit card expiration date. Here is how I am currently processing:

  1. I put a DropDownList of the 4-digit year on the page.
  2. I validate the expiration date in a DateTime field to be sure that the expiration date being passed to the CC processor isn't expired.
  3. I send a two-digit year to the CC processor (as required). I do this via a substring of the value from the year DDL.

Is there a method out there to convert a four-digit year to a two-digit year. I am not seeing anything on the DateTime object. Or should I just keep processing it as I am?

16 Answers

If you're creating a DateTime object using the expiration dates (month/year), you can use ToString() on your DateTime variable like so:

DateTime expirationDate = new DateTime(2008, 1, 31); // random date
string lastTwoDigitsOfYear = expirationDate.ToString("yy");

Edit: Be careful with your dates though if you use the DateTime object during validation. If somebody selects 05/2008 as their card's expiration date, it expires at the end of May, not on the first.

This should work for you:

public int Get4LetterYear(int twoLetterYear)
{
    int firstTwoDigits =
        Convert.ToInt32(DateTime.Now.Year.ToString().Substring(2, 2));
    return Get4LetterYear(twoLetterYear, firstTwoDigits);
}

public int Get4LetterYear(int twoLetterYear, int firstTwoDigits)
{
    return Convert.ToInt32(firstTwoDigits.ToString() + twoLetterYear.ToString());
}

public int Get2LetterYear(int fourLetterYear)
{
    return Convert.ToInt32(fourLetterYear.ToString().Substring(2, 2));
}

I don't think there are any special built-in stuff in .NET.

Update: It's missing some validation that you maybe should do. Validate length of inputted variables, and so on.

Use the DateTime object ToString with a custom format string like myDate.ToString("MM/dd/yy") for example.

Starting with c# 6.0 you can use the built-in composite formatting in string interpolation on anything that processes c#, like an MVC Razor page.

DateTime date = DateTime.Now;

string myTwoDigitYear = $"{date:yy};

No extensions necessary. You can use most of the standard date and time format strings after the colon after any valid DateTime object inside the curly brackets to use the built-in composite formatting.

At this point, the simplest way is to just truncate the last two digits of the year. For credit cards, having a date in the past is unnecessary so Y2K has no meaning. The same applies for if somehow your code is still running in 90+ years.

I'd go further and say that instead of using a drop down list, let the user type in the year themselves. This is a common way of doing it and most users can handle it.

I've seen some systems decide that the cutoff is 75; 75+ is 19xx and below is 20xx.

The answer is quite simple:

DateTime Today = DateTime.Today;
string zeroBased = Today.ToString("yy-MM-dd");

Why not have the original drop down on the page be a 2 digit value only? Credit cards only cover a small span when looking at the year especially if the CC vendor only takes in 2 digits already.

Here is a link to a 4Guys article on how you can format Dates and Times using the ToString() method by passing in a custom format string.

http://www.aspfaqs.com/aspfaqs/ShowFAQ.asp?FAQID=181

Just in case it goes away here is one of the examples.

'Create a var. named rightNow and set it to the current date/time
Dim rightNow as DateTime = DateTime.Now
Dim s as String 'create a string

s = rightNow.ToString("MMM dd, yyyy")

Since his link is broken here is a link to the DateTimeFormatInfo class that makes those formatting options possible.

http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx

It's probably a little more consistent to do something like that rather than use a substring, but who knows.

This seems to work okay for me. yourDateTime.ToString().Substring(2);

Even if a builtin way existed, it wouldn't validate it as greater than today and it would differ very little from a substring call. I wouldn't worry about it.

Related