
TimeSpan represents a length of time. You can create or manipulate TimeSpan instances using your C# program. The TimeSpan type provides many helper properties and methods. It is implemented as a struct type in the .NET Framework.
This C# tutorial demonstrates how to use TimeSpan structs. It provides many example programs.

First in this example, we see how you can use the TimeSpan instance constructor to create new TimeSpan structs. The TimeSpan constructor has several parameters and overloaded versions. You can use the IntelliSense feature in Visual Studio to browse through them and choose the best one for your program.
This example shows the TimeSpan constructor usage with five integer parameters. It creates a TimeSpan with a period of one day, two hours, and thirty seconds.
Program that uses TimeSpan constructor [C#]
using System;
class Program
{
static void Main()
{
// Use TimeSpan constructor to specify:
// ... Days, hours, minutes, seconds, milliseconds.
// ... The TimeSpan returned has those values.
TimeSpan span = new TimeSpan(1, 2, 0, 30, 0);
Console.WriteLine(span);
}
}
Output
1.02:00:30
The TimeSpan type has several public static methods that start with the word From. These include FromDays, FromHours, FromMinutes, FromSeconds, and FromMilliseconds. These allow you to convert a number of double type into a TimeSpan struct instance. The TimeSpan result will allow you to use the figure in a more natural way in C# programs and other methods. It is useful to pass a number that has a decimal place to the From methods.
Convert TimeSpan to LongProgram that uses TimeSpan.From methods [C#]
using System;
class Program
{
static void Main()
{
// Get time spans from a specific double unit of time.
// ... These allow easier manipulation of the time.
TimeSpan span1 = TimeSpan.FromDays(1);
TimeSpan span2 = TimeSpan.FromHours(1);
TimeSpan span3 = TimeSpan.FromMinutes(1);
TimeSpan span4 = TimeSpan.FromSeconds(1);
TimeSpan span5 = TimeSpan.FromMilliseconds(1);
Console.WriteLine(span1);
Console.WriteLine(span2);
Console.WriteLine(span3);
Console.WriteLine(span4);
Console.WriteLine(span5);
}
}
Output
1.00:00:00
01:00:00
00:01:00
00:00:01
00:00:00.0010000Here we look at the Add instance method on the TimeSpan type in the C# language. The TimeSpan.Add method receives one parameter of type TimeSpan. Note that structs such as TimeSpan are immutable and you can assign the result of the Add method to another TimeSpan variable. This program shows that when you add one minute to two minutes, you get three minutes.
Program that uses TimeSpan.Add method [C#]
using System;
class Program
{
static void Main()
{
// Adds a TimeSpan of one minute to a TimeSpan of two minutes.
// ... Then we get three minutes in a TimeSpan.
TimeSpan span1 = TimeSpan.FromMinutes(1);
TimeSpan span2 = TimeSpan.FromMinutes(2);
TimeSpan span3 = span1.Add(span2);
Console.WriteLine(span3);
}
}
Output
00:03:00In this example, we see how you can use the Subtract instance method on the TimeSpan variable. The Subtract method receives one argument of type TimeSpan, meaning the argument you pass is the TimeSpan you want to subtract. Typically, you will subtract the smaller TimeSpan from the larger TimeSpan, but not always. This program shows that when you subtract one second from one minute, you receive 59 seconds.
Program that uses TimeSpan.Subtract method [C#]
using System;
class Program
{
static void Main()
{
// Subtract TimeSpan of one second from one minute.
// ... The result is 59 seconds.
TimeSpan span1 = TimeSpan.FromMinutes(1);
TimeSpan span2 = TimeSpan.FromSeconds(1);
TimeSpan span3 = span1.Subtract(span2);
Console.WriteLine(span3);
}
}
Output
00:00:59We see the value returned when you access the MaxValue and MinValue fields, which are public static readonly fields. According to this program, the MaxValue is equal to over ten million days; this is sufficient for most programs. The MinValue is equal to negative ten million days.
Program that uses MaxValue and MinValue [C#]
using System;
class Program
{
static void Main()
{
// Write the maximum, minimum and zero values for TimeSpan.
Console.WriteLine(TimeSpan.MaxValue);
Console.WriteLine(TimeSpan.MinValue);
Console.WriteLine(TimeSpan.Zero);
}
}
Output
10675199.02:48:05.4775807
-10675199.02:48:05.4775808
00:00:00We look at the values of the TicksPerDay, TicksPerHour, TicksPerMinute, TicksPerSecond, and TicksPerMillisecond constants. These are constants and can be accessed with the composite name of the TimeSpan type. The constants show how many ticks occur in each of these normal time units; for example, there are ten thousand (10000) ticks in one millisecond.
Program that uses TicksPer constants [C#]
using System;
class Program
{
static void Main()
{
// Write the values for these Ticks Per constants.
Console.WriteLine(TimeSpan.TicksPerDay);
Console.WriteLine(TimeSpan.TicksPerHour);
Console.WriteLine(TimeSpan.TicksPerMinute);
Console.WriteLine(TimeSpan.TicksPerSecond);
Console.WriteLine(TimeSpan.TicksPerMillisecond);
}
}
Output
864000000000
36000000000
600000000
10000000
10000You can use the Duration static parameterless method on the TimeSpan type. This method takes the TimeSpan instance and converts it to the absolute value of itself. In other words, if you have a negative TimeSpan, this method will make the TimeSpan positive.
Program that uses Duration parameterless method [C#]
using System;
class Program
{
static void Main()
{
// Use the TimeSpan Duration method.
// ... This converts negative TimeSpans into positive TimeSpans.
// ... Same as absolute value of the time.
TimeSpan span = new TimeSpan(-1, -1, -1);
TimeSpan duration = span.Duration();
Console.WriteLine(duration);
}
}
Output
01:01:01Here we demonstrate the difference between the Hours instance property on TimeSpan, and the TotalHours instance property. This also applies to other properties such as Seconds and TotalSeconds, and Days and TotalDays. The Hours property returns the component of the TimeSpan that indicates hours; this is only a part of the entire time represented. The TotalHours property returns the entire time represented converted to a value represented in hours. This program shows that Hours is 20, but TotalHours is 500.
Program that uses Hours and TotalHours [C#]
using System;
class Program
{
static void Main()
{
// Shows the TimeSpan constructor, Hours and TotalHours.
// ... Hours is only a part of the time.
// ... TotalHours converts the entire time to hours.
TimeSpan span = new TimeSpan(0, 500, 0, 0, 0);
Console.WriteLine(span.Hours);
Console.WriteLine(span.TotalHours);
}
}
Output
20
500
The TimeSpan.Zero field is a public static field and it provides the exact representation of no time. The Zero field is useful because you cannot change the internal representation of the TimeSpan directly. The TimeSpan is an abstract data type that allows you to manipulate the time period from helper methods.
Program that uses TimeSpan.Zero value [C#]
using System;
class Program
{
static void Main()
{
// Demonstrate TimeSpan zero.
TimeSpan span = TimeSpan.Zero;
Console.WriteLine(span);
Console.WriteLine(span.TotalMilliseconds);
}
}
Output
00:00:00
0Accessing Zero public static field. When you access the TimeSpan.Zero field, the "load static field" intermediate language instruction is executed. This pushes the value onto the evaluation stack. Then, further instructions can use the value of the field in the stack-based virtual machine.

Implementation. Internally, the TimeSpan.Zero field is initialized in a static constructor in the TimeSpan type. It uses the TimeSpan constructor where the only argument is a long value of ticks. The argument used is 0L, which is zero in long format. In the TimeSpan(long) constructor, the field of name "_ticks" is assigned to the value of the parameter. Therefore, TimeSpan.Zero is a static field equal to "new TimeSpan(0)".
TimeSpan constructor [C#]
static TimeSpan()
{
Zero = new TimeSpan(0L);
MaxValue = new TimeSpan(9223372036854775807L);
MinValue = new TimeSpan(-9223372036854775808L);
}Tip: TimeSpan.Zero helps simplify usage of the TimeSpan abstract data type, and can be used to initialize TimeSpan variables and fields. Because there is only one instance of TimeSpan.Zero, accessing this field does not require any allocations, and it is therefore faster to use this field than to use "new TimeSpan(0L)".
This program demonstrates the TimeSpan.Parse and TimeSpan.TryParse methods. The Parse and TryParse methods are useful when reading in TimeSpans that may have been persisted as strings to files. The Parse and TryParse methods have similar internal logic, but TryParse is safer and faster for when you may encounter errors in the data, and it is usually better to use for this case.
Program that uses Parse and TryParse on TimeSpan [C#]
using System;
class Program
{
static void Main()
{
// Use TimeSpan.Parse method to parse in span string.
// ... Write it to the console.
TimeSpan span = TimeSpan.Parse("0:00:01");
Console.WriteLine(span);
// Use TimeSpan.TryParse to try to parse an invalid span.
// ... The result is TimeSpan.Zero.
TimeSpan span2;
TimeSpan.TryParse("X:00:01", out span2);
Console.WriteLine(span2);
}
}
Output
00:00:01
00:00:00
Parsing valid and invalid strings. This program first parses an entirely valid time span string; it specifies a span with zero hours, zero minutes, and one second. The program prints out the corresponding TimeSpan struct. Also, the program uses TryParse on an invalid time span string. This does not cause an exception to be thrown. If you were to use Parse on an invalid string, an exception would be thrown.
TryParse Overview
Usually TimeSpan instances are not the performance concern in your application, but in many programs TimeSpans are used on hot paths. For the benchmark, I compared creating a new TimeSpan with its FromHours method to the TimeSpan constructor, and also to copying a cached TimeSpan with its internal value already set.
Program that benchmarks TimeSpan [C#]
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
const int m = 100000000;
Stopwatch s1 = Stopwatch.StartNew();
for (int i = 0; i < m; i++)
{
TimeSpan span = TimeSpan.FromHours(1);
}
s1.Stop();
Stopwatch s2 = Stopwatch.StartNew();
for (int i = 0; i < m; i++)
{
TimeSpan span = new TimeSpan(1, 0, 0);
}
s2.Stop();
Stopwatch s3 = Stopwatch.StartNew();
TimeSpan cache = new TimeSpan(1, 0, 0);
for (int i = 0; i < m; i++)
{
TimeSpan span = cache;
}
s3.Stop();
Console.WriteLine("{0},{1},{2}", s1.ElapsedMilliseconds,
s2.ElapsedMilliseconds, s3.ElapsedMilliseconds);
Console.Read();
}
}What I found. The code that uses TimeSpan.FromHours is far slower than the other two examples. Using the TimeSpan constructor with three parameters [new TimeSpan(1, 0, 0)] was over two times faster.
TimeSpan performance test TimeSpan.FromHours(1): 1788 ms new TimeSpan(1, 0, 0): 989 ms Cache: 31 ms
How I discovered this. I was looking into the implementation of TimeSpan.FromHours, and saw some very complicated logic. Internally, TimeSpan.FromHours (TimeSpan.From*) has these instructions: 1 check, 1 multiply, 1 add, 1 check, 2 checks, 1 multiply, 1 cast, 1 constructor. For performance:
Avoid these TimeSpan methods TimeSpan.FromDays TimeSpan.FromHours TimeSpan.FromMilliseconds TimeSpan.FromMinutes TimeSpan.FromSeconds Prefer these TimeSpan constructors new TimeSpan(long) new TimeSpan(int, int int)
Tip: You can improve performance when using TimeSpan instances. When using dates and times, try to cache TimeSpans you will need repeatedly. For example, in an ASP.NET application, store the TimeSpan that indicates the HTTP cache duration. I eliminated wasted CPU cycles from a process that runs once every three seconds all day, every day.

We looked at many aspects of the TimeSpan struct type in the C# programming language. This type is a useful representation of periods of time in your programs, and it provides many helper methods and properties to improve time calculations. Certain other types, such as Stopwatch, also use TimeSpans for their representations.
StopWatch Time Representations