# C# 中的日期和时间

> 原文： [https://zetcode.com/csharp/datetime/](https://zetcode.com/csharp/datetime/)

在本教程中，我们展示了如何在 C# 中使用日期和时间。 [C# 教程](http://zetcode.com/lang/csharp/)是有关 C# 语言的综合教程。

## C# `DateTime`

`DateTime`值类型表示日期和时间，其值的范围是公历 0001 年 1 月 1 日凌晨 00:00:00（午夜）（公元）至 9999 年 12 月 31 日晚上 11:59:59（公元）。

## C# `TimeSpan`

`TimeSpan`表示时间间隔（时间或经过的时间），以天，小时，分钟，秒和几分之一秒的正数或负数测量。 `TimeZoneInfo`提供了时区信息和可用于不同时区的工具。

## C# 今天的日期

在第一个示例中，我们得到今天的日期。

`Program.cs`

```cs
using System;

namespace Today
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime now = DateTime.Now;
            Console.WriteLine(now.ToString("F"));
        }
    }
}

```

该示例打印今天的日期。

```cs
DateTime now = DateTime.Now;

```

通过`DateTime`的`Now`属性，我们可以获取当地时间的当前日期和时间。

```cs
Console.WriteLine(now.ToString("F"));

```

使用`ToString()`方法，我们格式化日期。 `F`说明符创建完整的日期和时间模式。

```cs
$ dotnet run
Tuesday, November 5, 2019 11:35:23 AM

```

这是程序的示例输出。

## C# `DateTime`属性

`DateTime`代表时间的瞬间。 它的属性提供日期和时间的各个方面。

`Program.cs`

```cs
using System;

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

            DateTime now = DateTime.Now;

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

```

该示例检查`DateTime`对象的属性。

```cs
DateTime now = DateTime.Now;

```

创建一个`DateTime`对象。 `DateTime`被设置为该计算机上的当前本地日期和时间。

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

```

`Date`属性获取`DateTime`实例的日期部分。

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

```

`Day`属性获取每月的某天。 `Month`属性返回月份部分，表示为 1 到 12 之间的值。

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

```

`DayOfYear`属性获取年份，`Year`属性获取年份。

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

```

`TimeOfDay`属性获取`DateTime`实例的一天中的时间。

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

```

`Hour`，`Minute`，`Second`和`Millisecond`是时间分量的一部分。

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

```

`DayOfWeek`属性获取星期几。

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

```

`Kind`属性返回一个值，该值指示此`DateTime`实例表示的时间是基于本地时间，世界协调时间（UTC）还是都不基于。

```cs
$ dotnet run
Today's date: 11/5/2019 12:00:00 AM
Today is 5 day of December
Today is 309 day of 2019
Today's time: 11:38:45.6791473
Hour: 11
Minute: 38
Second: 45
Millisecond: 679
The day of week: Tuesday
Kind: Local

```

This is a sample output of the program.

## C# 加减`DateTime`

`DateTime`具有进行时间算术运算的方法。

`Program.cs`

```cs
using System;

namespace TimeArithmetic
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dt = new DateTime(2019, 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);

            Console.WriteLine(dt1.ToString("F"));
            Console.WriteLine(dt2.ToString("F"));
            Console.WriteLine(dt3.ToString("F"));
            Console.WriteLine(dt4.ToString("F"));
            Console.WriteLine(dt5.ToString("F"));
            Console.WriteLine(dt6.ToString("F"));
            Console.WriteLine(dt7.ToString("F"));
        }
    }
}

```

该示例介绍了`DateTime`对象的六种方法。

```cs
DateTime dt1 = dt.AddSeconds(55);

```

`AddSeconds()`返回一个新的`DateTime`，该值将指定的秒数添加到该实例的值。

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

```

`AddDays()`为`DateTime`增加了几天。 我们可以提供正值或负值。

```cs
$ dotnet run
Friday, February 22, 2019 2:00:55 PM
Friday, February 22, 2019 2:30:00 PM
Monday, February 25, 2019 2:00:00 PM
Sunday, April 28, 2019 2:00:00 PM
Wednesday, December 19, 2018 2:00:00 PM
Wednesday, May 22, 2019 2:00:00 PM
Wednesday, February 22, 2023 2:00:00 PM

```

这是示例的输出。

## C# UTC 时间

我们的星球是一个球体； 它绕其轴旋转。 地球向东旋转，因此太阳在不同位置的不同时间升起。 地球大约每 24 小时旋转一次。 因此，世界被划分为 24 个时区。 在每个时区，都有一个不同的本地时间。 夏令时通常会进一步修改此本地时间。

实际需要一个全球时间。 全球时间可以避免时区和夏令时的混淆。 UTC（世界标准时间）被选为主要时间标准。 UTC 用于航空，天气预报，飞行计划，空中交通管制通关和地图。 与当地时间不同，UTC 不会随季节变化而变化。

`Program.cs`

```cs
using System;

namespace UniversalTime
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime now = DateTime.Now;
            DateTime utc = DateTime.UtcNow;

            Console.WriteLine($"UTC time {utc:HH:mm:ss}");
            Console.WriteLine($"Local time {now:HH:mm:ss}");
        }
    }
}

```

该示例打印当前的 UTC 时间和本地时间。

```cs
DateTime utc = DateTime.UtcNow;

```

通过`DateTime`的`UtcNow`属性，我们获得了 UTC 时间。

```cs
Console.WriteLine($"UTC time {utc:HH:mm:ss}");

```

我们格式化时间。

```cs
$ dotnet run
UTC time 10:48:16
Local time 11:48:16

```

对于 CET 时区，时差为一小时。

## C# 本地化日期

`DateTime`允许我们显示特定区域性的日期和时间。

`Program.cs`

```cs
using System;
using System.Globalization;

namespace Localized
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.OutputEncoding = System.Text.Encoding.UTF8;

            DateTime now = DateTime.Now;
            CultureInfo ci = new CultureInfo("sk-SK");

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

```

该示例打印斯洛伐克文化中的当前日期和时间。

```cs
Console.OutputEncoding = System.Text.Encoding.UTF8;

```

为了正确输出带重音的斯洛伐克语字符，我们将控制台输出编码设置为 UTF8。

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

```

我们创建了一个斯洛伐克语`CultureInfo`，其中包括有关区域性名称，书写系统，使用的日历，字符串的排序顺序以及日期和数字格式的信息。

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

```

我们以完整的日期和时间格式模式打印日期和时间。

```cs
$ dotnet run
Dnešný dátum a čas: utorok 5\. novembra 2019 12:03:25

```

这是程序的输出。

## C# Unix 时间

Unix 时间是自 Unix 时代以来的秒数。 Unix 时间广泛用于计算。 没有方法可以在 C# 中获得 Unix 时间。 我们需要创建自己的计算。

`Program.cs`

```cs
using System;

namespace UnixTime
{
    class Program
    {
        static void Main(string[] args)
        {
            long unixTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            Console.WriteLine(unixTime);
        }
    }
}

```

该示例显示 Unix 时间。

```cs
long unixTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

```

我们使用`ToUnixTimeSeconds()`方法获得 Unix 时间。

```cs
$ dotnet run
1572952370

```

此刻，自 Unix 时代以来已经过了`1572952370`秒。

## C# `TimeSpan`

`TimeSpan`结构表示时间间隔。

`subtract_times.cs`

```cs
using System;

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

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

            Console.WriteLine($"Time elapsed: {elapsed}");
        }
    }
}

```

在示例中，我们减去两个时间值。

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

```

我们定义了两个表示为字符串的时间值。

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

```

`Subtract()`方法用于减去两个时间值。 `Parse()`方法将时间间隔的字符串表示形式转换为`TimeSpan`对象。

```cs
$ dotnet run
Time elapsed: 13:30:00

```

区别是 13 小时 30 分钟。

在下面的示例中，我们减去两个日期值。

`Program.cs`

```cs
using System;

namespace BorodinoBattle
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime now = DateTime.Today;
            DateTime borodino_battle = new DateTime(1812, 9, 7);

            TimeSpan diff = now - borodino_battle;

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

```

在示例中，我们计算了自 Borodino 战斗以来经过的天数。

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

```

我们定义了两个`DateTime`对象：一个用于今天，另一个用于在 Borodino 战斗的日期。

```cs
TimeSpan diff = now - borodino_battle;

```

通过减去这两个对象，我们得到一个`TimeSpan`对象。

```cs
Console.WriteLine($"{diff.TotalDays} days have passed since the Battle of Borodino.");

```

`TotalDays`属性具有经过时间的天数。

```cs
$ dotnet run
75664 days have passed since the Battle of Borodino.

```

自 Borodino 战役以来，于 2019 年 11 月 5 日过去了 75664 天。

## C# 格式化时间

日期和时间格式字符串定义了由格式化操作产生的`DateTime`或`DateTimeOffset`值的文本表示形式。 格式说明符有两种类型：标准和自定义。 自定义日期和时间格式字符串由两个或多个字符组成。

`Program.cs`

```cs
using System;

namespace StandardSpecifiers
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime now = DateTime.Now;

            Console.WriteLine(now.ToString("d"));
            Console.WriteLine(now.ToString("D"));
            Console.WriteLine(now.ToString("F"));
            Console.WriteLine(now.ToString("M"));
            Console.WriteLine(now.ToString("o"));
            Console.WriteLine(now.ToString("R"));
            Console.WriteLine(now.ToString("t"));
            Console.WriteLine(now.ToString("T"));
            Console.WriteLine(now.ToString("Y"));
        }
    }
}

```

该示例使用某些标准格式说明符打印今天的日期。

```cs
Console.WriteLine(now.ToString("d"));

```

`d`说明符创建一个短日期模式。

```cs
Console.WriteLine(now.ToString("D"));

```

`D`说明符创建一个长日期模式。

```cs
Console.WriteLine(now.ToString("F"));

```

`F`说明符创建完整的日期和时间模式。

```cs
Console.WriteLine(now.ToString("M"));

```

`M`说明符创建月和日模式。

```cs
Console.WriteLine(now.ToString("o"));

```

`o`说明符创建往返日期和时间模式。 在此模式中，日期和时间部分由`T`字符分隔，并且时区偏差附加在字符串的末尾。

```cs
Console.WriteLine(now.ToString("R"));

```

`R`说明符创建一个 RFC1123 日期和时间模式。

```cs
Console.WriteLine(now.ToString("t"));

```

`t`说明符创建一个短时间模式。

```cs
Console.WriteLine(now.ToString("T"));

```

`t`说明符创建长时间模式。

```cs
Console.WriteLine(now.ToString("Y"));

```

`Y`说明符创建年和月模式。

```cs
$ dotnet run
11/5/2019
Tuesday, November 5, 2019
Tuesday, November 5, 2019 1:05:46 PM
November 5
2019-11-05T13:05:46.5778252+01:00
Tue, 05 Nov 2019 13:05:46 GMT
1:05 PM
1:05:46 PM
November 2019

```

This is the output of the example.

自定义格式说明符使我们可以创建自定义的日期和时间格式模式。

`Program.cs`

```cs
using System;

namespace CustomSpecifiers
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime now = DateTime.Now;

            Console.WriteLine(now.ToString("ddd MMM %d, yyyy"));
            Console.WriteLine(now.ToString("hh:mm:ss tt"));
        }
    }
}

```

该示例使用自定义说明符打印日期和时间格式。

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

```

`ddd`指示符是星期几的缩写名称，`MMM`是该月的缩写名，`d`是该月的某天，从 1 到 31。在自定义说明符的上下文中 ，它前面必须带有`%`字符。 最后，`yyyy`是四位数的年份。

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

```

`hh`说明符是小时，使用从 01 到 12 的 12 小时制时钟，`mm`是分钟，从 00 到 59，`ss`是秒，从 00 到 59，并且`tt`是 AM/PM 指示符。

```cs
$ dotnet run
Tue Nov 5, 2019
01:07:51 PM

```

This is the output of the program.

## C# 解析时间

`DateTime`的`Parse()`方法将日期和时间的字符串表示形式转换为其等效的`DateTime`。

`Program.cs`

```cs
using System;

namespace ParseTime
{
    class Program
    {
        static void Main(string[] args)
        {
            string date_string = "11/5/2019";

            DateTime dt = DateTime.Parse(date_string);

            Console.WriteLine($"{dt:d MMMM, yyyy}");
        }
    }
}

```

程序将日期解析为字符串。

```cs
string date_string = "11/5/2019";

```

这是一个以字符串表示的日期。

```cs
DateTime dt = DateTime.Parse(date_string);

```

使用`Parse()`方法，我们将其解析为`DateTime`对象。

```cs
Console.WriteLine($"{dt:d MMMM, yyyy}");

```

日期以中端顺序打印到控制台。

```cs
$ dotnet run
5 November, 2019

```

This is the output of the example.

## C# 时区

时区是一个使用相同标准时间的区域。 世界上有 24 个时区。

```cs
UTC = local time + bias

```

偏差是 UTC 时间与本地时间之间的时差。

`TimeZoneInfo`是用于使用 C# 中的时区的类。

`Program.cs`

```cs
using System;

namespace LocalZone
{
    class Program
    {
        static void Main(string[] args)
        {
            TimeZoneInfo localZone = TimeZoneInfo.Local;

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

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

```

该程序将打印当前时区和偏差。

```cs
TimeZoneInfo localZone = TimeZoneInfo.Local;

```

使用`Local`属性，我们可以获得本地时区。

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

```

`StandardName`给出时区的标准名称，`DaylightName`给出夏令时的名称。

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

```

`BaseUtcOffset`属性产生偏差。

```cs
$ dotnet run
Current timezone: Central Europe Standard Time
Daylight name: Central Europe Daylight Time
Bias: 01:00:00

```

在位于布拉迪斯拉发的系统上，我们获得了这些值。

`GetSystemTimeZones()`方法返回所有时区的排序集合，有关这些时区的信息在本地系统上可用。

`Program.cs`

```cs
using System;

namespace TimeZones
{
    class Program
    {
        static void Main(string[] args)
        {
            var timezones = TimeZoneInfo.GetSystemTimeZones();

            foreach (var timezone in timezones)
            {
                Console.WriteLine(timezone.Id);
            }
        }
    }
}

```

该示例在系统上打印可用时区的 ID。

```cs
$ dotnet run
...
Newfoundland Standard Time
Tocantins Standard Time
E. South America Standard Time
SA Eastern Standard Time
Argentina Standard Time
Greenland Standard Time
Montevideo Standard Time
Magallanes Standard Time
Saint Pierre Standard Time
Bahia Standard Time
UTC-02
Mid-Atlantic Standard Time
Azores Standard Time
Cape Verde Standard Time
UTC
...

```

这是程序的部分输出。

还可以使用某些格式说明符从`DateTime`值中检索时区信息。

`Program.cs`

```cs
using System;

namespace GetTimeZone
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime now = DateTime.Now;

            Console.WriteLine(now.ToString("%z"));
            Console.WriteLine(now.ToString("%K"));
            Console.WriteLine(now.ToString("o"));
        }
    }
}

```

该示例使用格式说明符来表示本地时区的偏差。

```cs
$ dotnet run
+1
+01:00
2019-11-05T13:02:26.2345688+01:00

```

这是反对。

## C# 闰年

闰年是包含另一天的年份。 日历中额外一天的原因是天文日历年与日历年之间的差异。

`Program.cs`

```cs
using System;

namespace LeapYears
{
    class Program
    {
        static void Main(string[] args)
        {
            // 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))
                {
                    Console.WriteLine($"{year} is a leap year");
                }
                else
                {
                    Console.WriteLine($"{year} is not a leap year");
                }
            }
        }
    }
}

```

我们有很多年。 我们检查所有年份是否为闰年。 `IsLeapYear()`函数确定年份是否为闰年。

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

```

这是我们检查的年份。 年份必须在公历中。

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

```

使用`for`循环，我们遍历数组。 我们使用`IsLeapYear()`函数检查年份是否为闰年。

```cs
$ dotnet run
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 program.

在本文中，我们使用 C# 处理日期和时间。 [在 C# 中读取网页](http://zetcode.com/csharp/readwebpage/)显示了几种在 C# 中抓取网页的方法。 [以 C# 读取文本文件](/csharp/readtext/)涵盖了使用流以 C# 读取文本文件的过程。