75

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?

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
Mike Wills
  • 20,959
  • 28
  • 93
  • 149
  • 6
    I am glad there isn't a build in method because I can just see it being used all the time for the wrong reason... re-introduce Y2K anyone? =) – Paul C Dec 03 '13 at 16:41

16 Answers16

129

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.

brock.holum
  • 3,133
  • 2
  • 20
  • 15
54

1st solution (fastest) :

yourDateTime.Year % 100

2nd solution (more elegant in my opinion) :

yourDateTime.ToString("yy")
Chris W
  • 1,562
  • 20
  • 27
  • 7
    Your 1st solution is useful when you only have an integer year to begin with, not a DateTime. – xr280xr Oct 07 '16 at 17:00
  • @xr280xr, Or if you want an integer as a result instead of a string. – tyjkenn May 15 '17 at 22:39
  • @xr280xr the first solution `yourDateTime.Year` already returns an integer. Not a `DateTime` – 0014 Dec 12 '18 at 21:39
  • @0014 I think I meant if you're only dealing with int years. E.G. if you have `int yourYear=2018;` instead of `yourDate`, then it works for `yourYear % 100` - no need to create a DateTime instance. – xr280xr Dec 12 '18 at 23:16
22

The answer is already given. But here I want to add something. Some person told that it did not work.

May be you are using

DateTime.Now.Year.ToString("yy");

that is why it is not working. I also made the same the mistake.

Change it to

DateTime.Now.ToString("yy");

Sadid Khan
  • 1,836
  • 20
  • 35
5

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.

Seb Nilsson
  • 26,200
  • 30
  • 103
  • 130
3

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.

JakeMc
  • 413
  • 6
  • 13
2

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.

NotMe
  • 87,343
  • 27
  • 171
  • 245
2

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

ckramer
  • 9,419
  • 1
  • 24
  • 38
2

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

spoulson
  • 21,335
  • 15
  • 77
  • 102
2
//using java script
var curDate = new Date();
var curYear = curDate.getFullYear();
curYear = curYear.toString().slice(2);
document.write(curYear)
//using java script
//using sqlserver
select Right(Year(getDate()),2)
//using sql server
//Using c#.net 
DateTime dt = DateTime.Now;
            string curYear = dt.Year.ToString().Substring(2,2).ToString()  ;
//using c#.net
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
1

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.

Andrew Jahn
  • 667
  • 10
  • 18
1

The answer is quite simple:

DateTime Today = DateTime.Today;
string zeroBased = Today.ToString("yy-MM-dd");
Iliass Nassibane
  • 651
  • 7
  • 15
  • You could write this in one line as well `string zeroBased = DateTime.Today.ToString("yy-MM-dd");` – Bojan B Oct 25 '16 at 08:32
1
DateTime.Now.Year - (DateTime.Now.Year / 100 * 100)

Works for current year. Change DateTime.Now.Year to make it work also for another year.

GSerg
  • 76,472
  • 17
  • 159
  • 346
Phiplex
  • 27
  • 1
0

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.

Vinko Vrsalovic
  • 330,807
  • 53
  • 334
  • 373
0

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.

Harv
  • 555
  • 6
  • 17
0

This is an old post, but I thought I'd give an example using an ExtensionMethod (since C# 3.0), since this will hide the implementation and allow for use everywhere in the project instead or recreating the code over and over or needing to be aware of some utility class.

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

public static class DateTimeExtensions
    {
        public static int ToYearLastTwoDigit(this DateTime date)
        {
            var temp = date.ToString("yy");
            return int.Parse(temp);
        }
    }

You can then call this method anywhere you use a DateTime object, for example...

var dateTime = new DateTime(2015, 06, 19);
var year = cob.ToYearLastTwoDigit();
Christian Phillips
  • 18,399
  • 8
  • 53
  • 82
0

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

John
  • 111
  • 2
  • 2