Date and time in C#

In this article, we show how to work with date and time in C#. C# tutorial is a comprehensive tutorial on C# language.

The DateTime value type represents dates and times with values ranging from 00:00:00 (midnight), January 1, 0001 Anno Domini (Common Era) through 11:59:59 P.M., December 31, 9999 A.D. (C.E.) in the Gregorian calendar.

TimeSpan represents a time interval (duration of time or elapsed time) that is measured as a positive or negative number of days, hours, minutes, seconds, and fractions of a second. TimeZoneInfo provides time zone information and tools to work with different time zones.

Today's date

In our first example, we get today's date.

today.cs
using static System.Console;
using System;

class Today 
{
    static void Main() 
    { 
        DateTime now = DateTime.Now;
        WriteLine(now.ToString("F"));
    }
}

The example prints today's date.

DateTime now = DateTime.Now;

With the Now property of the DateTime, we get the current date and time in local time.

WriteLine(now.ToString("F"));

With the ToString() method, we format the date. The F specifier creates a full date and time pattern.

$ ./today.exe 
Wednesday, February 24, 2016 3:37:01 PM

This is a sample output of the program.

DateTime properties

DateTime represents an instant in time. Its properties provide various aspects of the date and time.

datetime_properties.cs
using static System.Console;
using System;

class DateTimeProperties 
{
    static void Main() 
    { 
        string[] months = {"January", "February", "March", "April", "May", 
            "June", "July", "September", "October", "November", "December"};
    
        DateTime now = DateTime.Now;

        WriteLine("Today's date: {0}", now.Date);
        WriteLine("Today is {0} day of {1}", now.Day, months[now.Month - 1]);
        WriteLine("Today is {0} day of {1}", now.DayOfYear, now.Year);
        WriteLine("Today's time: {0}", now.TimeOfDay);
        WriteLine("Hour: {0}", now.Hour);
        WriteLine("Minute: {0}", now.Minute);
        WriteLine("Second: {0}", now.Second);
        WriteLine("Millisecond: {0}", now.Millisecond);        
        WriteLine("The day of week: {0}", now.DayOfWeek);
        WriteLine("Kind: {0}", now.Kind);
    }
}

The example examines properties of the DateTime object.

DateTime now = DateTime.Now;

A DateTime object is created. The DateTime is set to the current local date and time on this computer.

WriteLine("Today's date: {0}", now.Date);

The Date property gets the date component of the DateTime instance.

WriteLine("Today is {0} day of {1}", now.Day, months[now.Month - 1]);

The Day property gets the day of the month. The Month property returns the month component, expressed as a value between 1 and 12.

WriteLine("Today is {0} day of {1}", now.DayOfYear, now.Year);

The DayOfYear property gets the day of the year, and the Year gets the year.

WriteLine("Today's time: {0}", now.TimeOfDay);

The TimeOfDay property gets the time of day of the DateTime instance.

WriteLine("Hour: {0}", now.Hour);
WriteLine("Minute: {0}", now.Minute);
WriteLine("Second: {0}", now.Second);
WriteLine("Millisecond: {0}", now.Millisecond);   

The Hour, Minute, Second, and Millisecond are parts of the time component.

WriteLine("The day of week: {0}", now.DayOfWeek);

The DayOfWeek property gets the day of the week.

WriteLine("Kind: {0}", now.Kind);

The DayOfWeek property returns a value that indicates whether the time represented by this DateTime instance is based on local time, Coordinated Universal Time (UTC), or neither.

$ ./datetime_properties.exe 
Today's date: 2/24/2016 12:00:00 AM
Today is 24 day of February
Today is 55 day of 2016
Today's time: 15:12:07.1843150
Hour: 15
Minute: 12
Second: 7
Millisecond: 184
The day of week: Wednesday
Kind: Local

This is a sample output of the datetime_properties.exe program.

Adding and subtracting DateTime

DateTime has methods for doing time arithmetic operations.

addsub.cs
using static System.Console;
using System;

class TimeArithmetic 
{
    static void Main() 
    { 
        DateTime dt = new DateTime(2016, 2, 22, 14, 0, 0);

        DateTime dt1 = dt.AddSeconds(55);
        DateTime dt2 = dt.AddMinutes(30);
        DateTime dt3 = dt.AddHours(72);
        DateTime dt4 = dt.AddDays(65);
        DateTime dt5 = dt.AddDays(-65);
        DateTime dt6 = dt.AddMonths(3);
        DateTime dt7 = dt.AddYears(4);
        
        WriteLine(dt1.ToString("F"));
        WriteLine(dt2.ToString("F"));
        WriteLine(dt3.ToString("F"));
        WriteLine(dt4.ToString("F"));
        WriteLine(dt5.ToString("F"));
        WriteLine(dt6.ToString("F"));
        WriteLine(dt7.ToString("F"));
    }
}

The example presents six methods of the DateTime object.

DateTime dt1 = dt.AddSeconds(55);

The AddSeconds() returns a new DateTime that adds the specified number of seconds to the value of this instance.

DateTime dt4 = dt.AddDays(65);
DateTime dt5 = dt.AddDays(-65);

The AddDays() adds days to the DateTime. We can provide both positive or negative values.

$ ./addsub.exe 
Monday, February 22, 2016 2:00:55 PM
Monday, February 22, 2016 2:30:00 PM
Thursday, February 25, 2016 2:00:00 PM
Wednesday, April 27, 2016 2:00:00 PM
Saturday, December 19, 2015 2:00:00 PM
Sunday, May 22, 2016 2:00:00 PM
Saturday, February 22, 2020 2:00:00 PM

This is the output of the example.

UTC time

Our planet is a sphere; it revolves round its axis. The Earth rotates towards the east, so the Sun rises at different times in different locations. The Earth rotates once in about 24 hours. Therefore, the world was divided into 24 time zones. In each time zone, there is a different local time. This local time is often further modified by the daylight saving.

There is a pragmatic need for one global time. One global time helps to avoid confusion about time zones and daylight saving time. The UTC (Universal Coordinated time) was chosen to be the primary time standard. UTC is used in aviation, weather forecasts, flight plans, air traffic control clearances, and maps. Unlike local time, UTC does not change with a change of seasons.

utctime.cs
using static System.Console;
using System;

class UniversalTime 
{
    static void Main() 
    { 
        DateTime now = DateTime.Now;
        DateTime utc = DateTime.UtcNow;
        
        WriteLine(string.Format("UTC time {0:HH:mm:ss}", utc));
        WriteLine(string.Format("Local time {0:HH:mm:ss}", now));
    }
}

The example prints the current UTC time and the local time.

DateTime utc = DateTime.UtcNow;

With the UtcNow property of the DateTime, we get the UTC time.

WriteLine(string.Format("UTC time {0:HH:mm:ss}", utc));

The string.Format() method is used to format the time.

$ ./utctime.exe 
UTC time 18:52:28
Local time 19:52:28

For the CET time zone, there is one hour difference in time.

Localized date

The DateTime allows us to display the date and time in a specific culture.

localized.cs
using static System.Console;
using System.Globalization;
using System;

class Localized 
{
    static void Main() 
    { 
        DateTime now = DateTime.Now;
        CultureInfo ci = new CultureInfo("sk-SK");

        Console.WriteLine("Dnešný dátum a čas: {0}", now.ToString("F", ci));
    }
}

The example prints the current date and time in Slovak culture.

CultureInfo ci = new CultureInfo("sk-SK");

We create a Slovak CultureInfo, which includes information about the names for the culture, the writing system, the calendar used, the sort order of strings, and formatting for dates and numbers.

Console.WriteLine("Dnešný dátum a čas: {0}", now.ToString("F", ci));

We print the date and time in full date and time format pattern.

$ ./localized.exe 
Dnešný dátum a čas: 23. februára 2016 13:42:39

This is the output of the localized.exe program.

Unix time

The Unix time is the number of seconds since the Unix epoch. The Unix time is widely used in computing. There is no method to get Unix time in C#. We need to create our own calculation.

unixtime.cs
using static System.Console;
using System;

class UnixTime 
{
    static void Main() 
    { 
        DateTime now = DateTime.UtcNow;
        DateTime startOfUnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime();
        
        TimeSpan tspan = now - startOfUnixEpoch;
        long secs = (long) tspan.TotalSeconds;
        
        WriteLine("Unix time: {0}", secs);
    }
}

The example prints the Unix time.

DateTime now = DateTime.UtcNow;

The DateTime object is set to the current date and time expressed as the Coordinated Universal Time (UTC).

DateTime startOfUnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime();

We get a DateTime object for the start of the Unix epoch, in UTC time.

TimeSpan tspan = now - startOfUnixEpoch;

A TimeSpan object is calculated by subtracting DateTime object of now and of the start of the Unix epoch.

long secs = (long) tspan.TotalSeconds;

With the TotalSeconds property, we get the number of seconds for the time interval.

$ ./unixtime.exe 
Unix time: 1456083646

At this moment, 1456083646 have passed since the Unix epoch.

TimeSpan

A TimeSpan structure represents a time interval.

subtract_times.cs
using static System.Console;
using System;

class SubtractingTimes 
{
    static void Main() 
    { 
        string startTime = "7:00 AM";
        string endTime = "8:30 PM";

        TimeSpan elapsed = DateTime.Parse(endTime).Subtract(DateTime.Parse(startTime));
        
        WriteLine($"Time elapsed: {elapsed}");
    }
}

In the example, we subtract two time values.

string startTime = "7:00 AM";
string endTime = "8:30 PM";

We define two time values expressed as strings.

TimeSpan elapsed = DateTime.Parse(endTime).Subtract(DateTime.Parse(startTime));

The Subtract() method is used to subtract two time values. The Parse() method converts the string representation of a time interval to a TimeSpan object.

$ ./subtract_times.exe 
Time elapsed: 13:30:00

The difference is 13 hours and 30 minutes.

In the following example, we subtract two date values.

borodino_battle.cs
using static System.Console;
using System;

class BorodinoBattle 
{
    static void Main() 
    { 
        DateTime now = DateTime.Today;
        DateTime borodino_battle = new DateTime(1812, 9, 7);

        TimeSpan diff = now - borodino_battle;
        
        WriteLine("{0} days have passed since the Battle of Borodino.", diff.TotalDays);
    }
}

In the example, we compute the number of days passed since the Borodino battle.

DateTime now = DateTime.Today;
DateTime borodino_battle = new DateTime(1812, 9, 7);

We define two DateTime objects: one for today and one for the date of the Borodino battle.

TimeSpan diff = now - borodino_battle;

By subtracting those two objects, we get a TimeSpan object.

WriteLine("{0} days have passed since the Battle of Borodino.", diff.TotalDays);

The TotalDays property has the number of days of the elapsed time.

$ ./borodino_battle.exe 
74313 days have passed since the Battle of Borodino.

On February 23, 2016, 74313 days have passed since the Battle of Borodino.

Formatting time

A date and time format string defines the text representation of a DateTime or DateTimeOffset value that results from a formatting operation. There are two types of format specifiers: standard and custom. A custom date and time format string consists of two or more characters.

standard_specifiers.cs
using static System.Console;
using System;

class StandardSpecifiers 
{
    static void Main() 
    { 
        DateTime now = DateTime.Now;
        
        WriteLine(now.ToString("d"));
        WriteLine(now.ToString("D"));
        WriteLine(now.ToString("F"));
        WriteLine(now.ToString("M"));
        WriteLine(now.ToString("o"));
        WriteLine(now.ToString("R"));
        WriteLine(now.ToString("t"));
        WriteLine(now.ToString("T"));
        WriteLine(now.ToString("Y"));
    }
}

The example prints today's date using some of the standard format specifiers.

WriteLine(now.ToString("d"));

The d specifier creates a short date pattern.

WriteLine(now.ToString("D"));

The D specifier creates a long date pattern.

WriteLine(now.ToString("F"));

The F specifier creates a full date and time pattern.

WriteLine(now.ToString("M"));

The M specifier creates a month and day pattern.

WriteLine(now.ToString("o"));

The o specifier creates a round-trip date and time pattern. In this pattern, the date and time parts are separated by the T character and the time zone bias is appended at the end of the string.

WriteLine(now.ToString("R"));

The R specifier creates an RFC1123 date and time pattern.

WriteLine(now.ToString("t"));

The t specifier creates a short time pattern.

WriteLine(now.ToString("T"));

The t specifier creates a long time pattern.

WriteLine(now.ToString("Y"));

The Y specifier creates a year and month pattern.

$ ./standard_specifiers.exe 
2/23/2016
Tuesday, February 23, 2016
Tuesday, February 23, 2016 2:11:08 PM
February 23
2016-02-23T14:11:08.6916300+01:00
Tue, 23 Feb 2016 14:11:08 GMT
2:11 PM
2:11:08 PM
February 2016

This is the output of the example.

Custom format specifiers allow us to create customized date and time format patterns.

custom_specifiers.cs
using static System.Console;
using System;

class CustomSpecifiers 
{
    static void Main() 
    { 
        DateTime now = DateTime.Now;
        
        WriteLine(now.ToString("ddd MMM %d, yyyy"));
        WriteLine(now.ToString("hh:mm:ss tt"));
    }
}

The example prints a date and a time format using custom specifiers.

WriteLine(now.ToString("ddd MMM %d, yyyy"));

The ddd specifier is the abbreviated name of the day of the week, the MMM is the abbreviated name of the month, the d is the day of the month, from 1 through 31. In the context of custom specifiers, it must be preceded with the % character. Finally, the yyyy is the year as a four-digit number.

WriteLine(now.ToString("hh:mm:ss tt"));

The hh specifier is the hour, using a 12-hour clock from 01 to 12, the mm is the minute, from 00 through 59, the ss is the second, from 00 through 59, and the tt is the AM/PM designator.

$ ./custom_specifiers.exe 
Tue Feb 23, 2016
02:30:54 PM

This is the output of the custom_specifiers.exe program.

Parsing time

The DateTime's Parse() method converts the string representation of a date and time to its DateTime equivalent.

parsetime.cs
using static System.Console;
using System;

class ParseTime 
{
    static void Main() 
    { 
        string date_string = "8/11/2016";

        DateTime dt = DateTime.Parse(date_string);
        
        WriteLine(string.Format("{0:d MMMM, yyyy}", dt));
    }
}

The program parses a date in a string.

string date_string = "8/11/2016";

This is a date expressed in a string.

DateTime dt = DateTime.Parse(date_string);

With the Parse() method, we parse it into the DateTime object.

WriteLine(string.Format("{0:d MMMM, yyyy}", dt));

The date is printed to the console in a middle-endian order.

$ ./parsetime.exe 
11 August, 2016

This is the output of the parsetime.exe example.

Time zones

A time zone is a region throughout which the same standard time is used. There are 24 time zones in the world.

UTC = local time + bias

The bias is the difference between UTC time and local time.

TimeZoneInfo is a class for working with time zones in C#.

timezone.cs
using static System.Console;
using System;

class TimeZoneEx
{
    static void Main() 
    { 
        TimeZoneInfo localZone = TimeZoneInfo.Local;
    
        WriteLine("Current timezone: {0}", localZone.StandardName); 
        WriteLine("Daylight name: {0}", localZone.DaylightName); 
        
        WriteLine("Bias: {0}", localZone.BaseUtcOffset);    
    }
}

The program prints the current time zone and the bias.

TimeZoneInfo localZone = TimeZoneInfo.Local;

Using the Local property, we get the local time zone.

WriteLine("Current timezone: {0}", localZone.StandardName); 
WriteLine("Daylight name: {0}", localZone.DaylightName); 

The StandardName gives the time zone's standard name and the DaylightName its daylight saving name.

WriteLine("Bias: {0}", localZone.BaseUtcOffset);

The BaseUtcOffset property produces the bias.

$ ./timezone.exe 
Current timezone: CET
Daylight name: CEST
Bias: 01:00:00

On a system located in Bratislava, we get these values.

The GetSystemTimeZones() method returns a sorted collection of all the time zones about which information is available on the local system.

timezones.cs
using static System.Console;
using System;

class TimeZonesEx
{
    static void Main() 
    { 
        var timezones = TimeZoneInfo.GetSystemTimeZones();
        
        foreach (var timezone in timezones)
        {
            Console.WriteLine(timezone.Id);
        }
    }
}

The example prints the Ids of available time zones on a system.

$ ./timezones.exe 
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
...

This is a partial output of the timezones.exe program.

Timezone information can also be retrieved from a DateTime value with some format specifiers.

timezone2.cs
using static System.Console;
using System;

class TimeZoneEx
{
    static void Main() 
    { 
        DateTime now = DateTime.Now;
    
        WriteLine(now.ToString("%z")); 
        WriteLine(now.ToString("%K"));
        WriteLine(now.ToString("o"));
    }
}

The example the local time zone's bias using format specifiers.

$ ./timezone2.exe 
+1
+01:00
2016-02-24T13:21:31.0536990+01:00

This is the timezone2.exe program.

Leap year

A leap year is a year containing an additional day. The reason for an extra day in the calendar is the difference between the astronomical and the calendar year.

leapyears.cs
using static System.Console;
using System;

class LeapYears
{
    static void Main() 
    { 
        // Assume year >= 1582 in the Gregorian calendar.
        int[] years = { 2000, 2002, 2004, 2008, 2012, 2016, 2020,
                        1900, 1800, 1600 };
    
        foreach (int year in years) 
        {
            if (DateTime.IsLeapYear(year)) 
            {
                WriteLine($"{year} is a leap year");
            } else
            {
                WriteLine($"{year} is not a leap year");
            }
        }    
    }
}

We have an array of years. We check all years if they are leap years or not. The IsLeapYear() function determines whether a year is a leap year.

int[] years = { 2000, 2002, 2004, 2008, 2012, 2016, 2020,
                1900, 1800, 1600 };

This is an array of years that we check. The years must be in the Gregorian calendar.

foreach (int year in years) 
{
    if (DateTime.IsLeapYear(year)) 
    {
        WriteLine($"{year} is a leap year");
    } else
    {
        WriteLine($"{year} is not a leap year");
    }
}    

With the for loop we traverse the array. We check if a year is a leap year using the IsLeapYear() function.

$ ./leapyears.exe 
2000 is a leap year
2002 is not a leap year
2004 is a leap year
2008 is a leap year
2012 is a leap year
2016 is a leap year
2020 is a leap year
1900 is not a leap year
1800 is not a leap year
1600 is a leap year

This is the output of the leapyears.exe program.

In this article, we have worked with date and time in C#. Reading a web page in C# shows several ways how to scrape a web page in C#. Reading text files in C# covers reading text files in C# using streams.