>> >> >> Reference << << << <<<<<<Ref>>>>>>
>> >> >> Indexer << << << <<<<<<Idx>>>>>>
Matched: 0

Tags

    Categories

      Types

        Top Results

          Date Time
          M: 2025-06-01 - ljf12825

          基础时间类型概览

          C#中处理时间的核心结构体包括:

          类型名定义于功能简介
          DateTimeSystem最常用的时间表示类型,包含日期、时间、精度到 100ns。
          TimeSpanSystem表示两个 DateTime 之间的差值,或一个持续时间。
          DateTimeKindSystem枚举类型,用于标识 DateTimeLocalUtc 还是未指定。
          DateTimeOffsetSystem带时区偏移的时间,精确跨时区时间管理。

          DateTime:标准时间表示

          特性\

          • 精度:100纳秒(Ticks)
          • 范围:0001/1/1到9999/12/31
          • 内部存储:以64位整数表示ticks(从公元0001-01-01起的刻度数)
          DateTime now = DateTime.Now; // 本地时间
          DateTime utc = DateTime.UtcNow; // UTC时间
          DateTime specific = new DateTime(2025, 8, 1, 14, 30, 0); // 自定义时间
          

          常用属性

          now.Year;         // 年
          now.Month;        // 月
          now.Day;          // 日
          now.Hour;         // 小时
          now.Minute;       // 分钟
          now.Second;       // 秒
          now.Millisecond;  // 毫秒
          now.DayOfWeek;    // 星期几
          now.DayOfYear;    // 一年中的第几天
          

          TimeSpan:时间间隔

          特性\

          • 表示时间间隔而非具体时间点
          • 支持负值
          • 精度:100纳秒
          TimeSpan span = new TimeSpan(2, 30, 0); // 2h 30min
          DateTime t1 = DateTime.Now;
          DateTime t2 = t1.Add(span); // 加时间间隔
          TimeSpan delta = t2 - t1; // 时间差计算
          

          常用属性

          span.TotalHours; // 2.5
          span.Minutes; // 30
          span.TotalMilliseconds;
          

          DateTimeKind:时间语义标识

          枚举值

          public enum DateTimeKind
          {
              Unspecified, // 未指定,默认构造是这个
              Utc, // UTC时间
              Local // 本地时间
          }
          

          用法示例

          DateTime dt = new DateTime(2025, 8, 1, 12, 0, 0, DateTimeKind.Utc);
          DateTimeKind kind = dt.Kind; // Utc
          

          注意:DateTime.Now.Kind == Local, DateTime.UtcNow.Kind = Utc

          DateTimeOffset:带时区偏移的时间表示

          特性\

          • 表示一个“绝对”时间点(时间 + 偏移量)
          • 精确管理跨时区的场景(如数据库、国际化系统)
          • 能避免DateTime的时区歧义问题
          DateTimeOffset dto = DateTimeOffset.Now; // 当前本地时间,time + offset (H:mm:ss + 00:00)
          DateTimeOffset utcDto = DateTimeOffset.UtcNow; // UTC时间,格式同上
          DateTimeOffset custom = new DateTimeOffset(2025, 8, 1, 12, 0, 0, TimeSpan.FromHours(8)); // 手动设置当前时间和offset
          
          DateTime utc = dto.UtcDateTime; // 转utc,DateTime类型
          DateTime local = dto.LoaclDateTime; // 转本地
          

          时间的创建与格式化

          创建DateTime的方式

          构造函数

          DateTime dt = new DateTime(2025, 8, 1); // 2025-08-01 00:00:00
          DateTime full = new DateTime(2025, 8, 1, 14, 30. 0); // 带时间
          DateTime withKind = new DateTime(2025, 8, 1, 14, 30, 0, DateTimeKind.Utc); // 指定时区语义
          

          静态属性

          DateTime now = DateTime.Now;         // 当前本地时间
          DateTime utcNow = DateTime.UtcNow;   // 当前UTC时间
          DateTime today = DateTime.Today;     // 今天的00:00:00
          

          特殊用途

          DateTime min = DateTime.MinValue; // 0001-01-01
          DateTime max = DateTime.MaxValue; // 9999-12-31
          

          格式化输出ToString

          使用ToString()输出时间字符串,支持多种格式

          标准格式字符串(大小写敏感)

          格式示例含义
          d8/1/2025短日期
          DFriday, August 1, 2025长日期
          t14:30短时间
          T14:30:00长时间
          fFriday, August 1, 2025 14:30长日期+短时间
          FFriday, August 1, 2025 14:30:00长日期+长时间
          o2025-08-01T14:30:00.0000000+08:00ISO 8601(Round-trip)
          string s1 = DateTime.Now.ToString("F");
          

          自定义字符串格式

          字符含义示例
          yyyy2025
          MM月(两位)08
          dd01
          HH时(24制)14
          mm30
          ss05
          fff毫秒123
          string str = now.ToString("yyyy-MM-dd HH:mm:ss.fff");
          // 输出示例:2025-08-01 14:30:00.123
          

          字符串解析 Parse/TryParse/ParseExact

          Parse(可能抛异常)

          DateTime dt = DateTime.Parse("2025-08-01 14:30");
          

          TryParse(推荐)

          bool success = DateTime.TryParse("2025-08-01", out DateTime dt);
          if (success) {
              // 成功解析
          }
          

          ParseExact(精确控制格式)

          string input = "2025/08/01 14:30";
          DateTime dt = DateTime.ParseExact(input, "yyyy/MM/dd HH:mm", CultureInfo.InvariantCulture);
          

          ParseParseExact默认使用当前系统区域设置(文化信息)

          常见问题

          问题原因与解决方案
          输入字符串格式不对使用 TryParseParseExact 防止异常
          Parse 出现时区歧义使用 DateTimeOffset.Parse 更安全
          毫秒信息丢失或不一致明确格式字符串 fff,注意数据源精度
          文化差异导致解析失败使用 CultureInfo.InvariantCulture 明确文化设置

          时间计算与比较

          Add方法

          Add系列方法允许对DateTime添加不同类型的时间单位

          方法参数类型说明
          AddDays(double)double添加天数,支持负数
          AddHours(double)double添加小时,支持负数
          AddMinutes(double)double添加分钟,支持负数
          AddSeconds(double)double添加秒,支持负数
          AddMilliseconds(double)double添加毫秒,支持负数
          AddTicks(long)long添加刻度数(100纳秒为单位)
          DateTime now = DateTime.Now;
          DateTime tomorrow = now.AddDays(1);   // 明天同一时刻
          DateTime nextHour = now.AddHours(1);  // 一小时后
          DateTime lastMinute = now.AddMinutes(-1); // 一分钟前
          

          时间差计算

          通过-运算符或Subtract方法来计算两个DateTime之间的差值,返回的是TimeSpan类型

          DateTime t1 = new DateTime(2025, 8, 1, 14, 30, 0);
          DateTime t2 = DateTime.Now;
          TimeSpan difference = t2- t1; // t2和t1之间的差值
          

          TimeSpan常用属性

          • TotalDays:总天数
          • TotalHours:总小时数
          • Days:整数天数
          • Hours:小时数
          • Minutes:分钟数
          • Seconds:秒数

          比较DateTime对象

          可以使用 CompareTo><== 运算符来比较两个 DateTime 对象的大小

          DateTime dt1 = DateTime.Now;
          DateTime dt2 = DateTime.UtcNow;
          
          int comparison = dt1.CompareTo(dt2);
          if (comparison < 0)
              Console.WriteLine("dt1 是早于 dt2 的时间");
          else if (comparison > 0)
              Console.WriteLine("dt1 是晚于 dt2 的时间");
          else
              Console.WriteLine("dt1 与 dt2 相等");
          
          if (dt1 > dt2)
              Console.WriteLine("dt1 晚于 dt2");
          

          判断时间是否在某个区间内

          使用DateTime.Compare>=,<=

          DateTime start = new DateTime(2025, 8, 1, 0, 0, 0);
          DateTime end = new DateTime(2025, 8, 1, 23, 59, 59);
          DateTime target = DateTime.Now;
          
          if (target >= start && target <= end)
              Console.WriteLine("目标时间在区间内");
          else
              Console.WriteLine("目标时间不在区间内");
          

          判断某个DateTime是否为今天,可以仅比较年、月、日部分,忽略具体时间

          bool isToday = taget.Date == DateTime.Now.Date;
          

          target.Date会把时间部分归零,方便直接与今天进行比较

          判断时间是否在一小时内

          bool inWithinLastHour(DateTime target) => target >= DateTime.Now.AddHours(-1) && target <= DateTime.Now;
          

          DateTime对象的不可变性

          DateTime是不可变类型,所有Add操作都会返回一个新的DateTime对象,而不会修改源对象

          DateTime original = DateTime.Now;
          DateTime added = original.AddDays(1); // new DateTime对象
          Console.WriteLine(original);  // 还是原始时间
          Console.WriteLine(added);     // 添加后的新时间
          

          如果需要多次修改时间,建议使用DateTimeOffset或者TimeSpan来进行中间计算,避免不必要的重复创建

          时间戳的处理与转换

          在很多应用场景中,需要将时间转换为时间戳(Unix时间戳),或者将时间戳转换为DateTime对象

          Unix时间戳

          Unix 时间戳 是从 1970年1月1日 00:00:00 UTC 起经过的秒数(不计闰秒)。通常用于跨平台系统中,尤其是网络通信、数据库存储等。

          • Unix 时间戳 采用 秒级精度,因此是一个 32位 或 64位 整数(根据平台的不同)
          • 如果需要更高的精度(如毫秒或微秒),可以使用 DateTimeOffsetStopwatch 来实现

          获取当前Unix时间戳

          1. Unix时间戳(秒) 可以通过 DateTimeOffsetToUnixTimeSeconds() 方法获取当前时间的 Unix 时间戳(秒)
          DateTimeOffset now = DateTimeOffset.Now;
          long unixTimestampSeconds = now.ToUnixTimeSeconds();
          
          1. Unix时间戳(毫秒) 如果需要毫秒级精度,可以使用ToUnixTimeMilliseconds()方法
          long unixTimestampMilliseconds = nnow.ToUnixTimeMilliseconds();
          

          返回毫秒

          时间戳转DateTime

          1. Unix(秒)转DateTime
          long unixTimestamp = 1659388800; // 示例时间戳(2022-08-01 00:00:00 UTC)
          DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(unixTimestamp);
          DateTime dateTime = dateTimeOffset.DateTime;
          
          1. Unix(毫秒)转DateTime
          long unixTimestampMs = 1659388800000; // 毫秒级时间戳
          DateTimeOffset dateTimeOffsetMs = DateTimeOffset.FromUnixTimeMilliseconds(unixTimestampMs);
          DateTime dateTimeMs = dateTimeOffsetMs.DateTime;
          Console.WriteLine(dateTimeMs);  // 输出:2022-08-01 00:00:00
          

          DateTimeOffset与时间戳的结合

          DateTimeOffset表示一个时间点,并带有时区偏移,适合跨时区和国际化应用

          使用DateTimeOffset来转换时间戳时,会比直接使用DateTime更为安全和方便

          DateTimeOffset nowOffset = DateTimeOffset.Now;
          long unixTimestamp = nowOffset.ToUnixTimeSeconds();
          

          定时与定时工具

          时区管理

          时区问题是跨平台开发中常见的挑战之一,C#提供了TimeZoneInfo类来帮助管理和转换时区信息

          TimeZoneInfo类概述

          TimeZoneInfo类提供了时区相关的功能,允许查询、转换和处理不同的时区信息

          TimeZoneInfo的基本操作

          • 获取本地时区:TimeZoneInfo.Local
          • 获取UTC时区:TimeZoneInfo.Utc
          • 获取所有时区信息:TimeZoneInfo.GetSystemTimeZones()
          // 获取所有系统时区
          foreach (var timeZone in TimeZoneInfo.GetSystemTimeZones())
          {
              Console.WriteLine(timeZone.Id);  // 打印时区ID
          }
          

          TimeZoneInfo转换时间

          通过TimeZoneInfo,可以将一个时间从一个时区转换到另一个时区,常见的转换方法包括

          • 将本地时间转换为UTC时间
          • 将UTC时间转换为本地时间
          • 不同时区之间的相互转换
          // 本地转UTC
          DateTime localTime = DateTime.Now;
          DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(localTime);
          
          // UtC转本地
          DateTime utcTime = DateTime.UtcNow;
          DateTime localTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.Local);
          
          // 不同时区转换
          DateTime utcTime = DateTime.UtcNow;
          TimeZoneInfo timeZoneNewYourk = TImeZoneInfo.FindSystemTimeZondById("Eastern Standard Time"); // 获取纽约时区
          DateTime newYorkTime = TImeZoneInfo.ConvertTimeFromUtc(utcTime, timeZoneNewYork);
          

          使用TimeZoneInfo获取时区的详细信息

          TimeZoneInfo提供了一些方法,可以获取时区的详细信息,例如:标准时间偏移、夏令时的开始和结束时间等

          // 获取时区的偏移量
          TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
          TimeSpan offset = tzInfo.GetUtcOffset(DateTime.Now); // 获取当前时区的偏移量
          
          // 获取时区的夏令时信息
          TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
          if (tzInfo.SupportsDaylightSavingTime)
          {
              Console.WriteLine($"夏令时开始:{tzInfo.GetAdjustmentRules()[0].DateStart}");
              Console.WriteLine($"夏令时结束: {tzInfo.GetAdjustmentRules()[0].DateEnd}");
          }
          

          使用DateTimeOffset管理时区

          DateTimeOffset是一个结合了时间和时区偏移的类型,特别适合在国际化系统中使用,能明确表示时间的“绝对值”

          // 获取`DateTimeOffset和时区信息
          DateTimeOffset dto = DateTimeOffset.Now;
          
          // 使用DateTimeOffset在不同时间区之间转换
          DateTimeOffset dtUtc = DateTimeOffset.UtcNow; // 当前UTC时间
          DateTimeOffset dtLoacl = dtUtcToOffset(TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow)); // 转为本地时间
          

          时间与夏令时(DST)处理

          夏令时(DST)是某些时区的特殊情况,在夏令时期间,时间会比标准时间提前一个小时

          // 判断句某个日期是否在夏令时内
          TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
          DateTime testDate = new DateTime(2025, 7, 1); // 夏季
          bool isDST = tzInfo.IsDaylightSavingTime(testDate);
          
          // 获取夏令时调整规则
          TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
          foreach (var rule in tzInfo.GetAdjustmentRules())
          {
              Console.WriteLine($"{rule.DateStart}, {rule.DateEnd}");
          }
          

          定时与计时工具

          使用System.Timers.Timer定时器

          System.Timers.Timer是C#中用于定时任务执行的类,它可以在指定的时间间隔后执行某个事件或回调函数,适用于需要定期触发任务的场景

          创建并使用System.Timers.Timer

          using System;
          using System.Timers;
          
          class Program
          {
              static void Main()
              {
                  Timer timer = new Timer(1000); // 设置间隔为1s
                  timer.Elapsed += OnTimedEvent; // 事件触发时调用
                  timer.AutoReset = true; // 是否重复触发
                  timer.Enable = true; // 启动定时器
          
                  Console.WriteLine("Press Enter to exit...");
                  Console.ReadLine(); // 保持程序运行    
              }
              private static void OnTimedEvent(Object source, ElapsedEventArgs e)
              {
                  Console.WriteLine($"The event was triggered at {e.SignalTime}");
              }
          }
          

          关键属性和方法

          • Interval:设置事件间隔
          • Elapsed:事件,定时器到达指定和时间时触发
          • AudoReset:是否在每个间隔后重新启动定时器
          • Enabled:启用或禁用定时器

          使用System.Threading.Timer

          System.Threading.Timer也是一个定时器,但它运行在线程池线程上,适合在多线程环境下使用

          它的使用方式略有不同,适用于短期内要触发一次或周期性任务的场景

          创建并使用System.Threading.Timer

          using System;
          using System.Threading;
          
          class Program
          {
              staitc void Main()
              {
                  TimerCallback callback = new TimerCallback(OnTimedEvent);
                  Timer timer = new Timer(callback, null, 0, 1000); // 初始延迟为0ms,每1秒触发一次
          
                  Console.WriteLine("Press Enter to exit...");
                  Console.ReadLine();
              }
          
              private static void OnTimedEvent(Object state)
              {
                  Console.WriteLine($"The event was triggered at {DateTime.Now}");
              }
          }
          
          • callback:回调方法,在定时器触发时执行
          • dueTime:首次触发的延迟事件
          • period:定时器触发的间隔时间,可以设置为Timeout.Infinite使其只触发一次

          Stopwatch性能计时

          Stopwatch是C#提供的高精度计时工具,通常用于测量代码块的执行时间

          它不受系统时钟的影响,并且提供微秒级的精度

          它比DateTime更精确,并且可以支持微秒级别的计时

          Stopwatch stopwatch = new Stopwatch();
          stopwatch.Start();
          // do something
          stopwatch.Stop();
          Console.WriteLine(stopwatch.ElapsedMilliseconds); // 以毫秒为单位的高精度时间戳
          Console.WriteLine(stopwatch.Elapsed); // 输出更详细的时间间隔
          

          使用System.Threading.Thread.Sleep延时

          Thread.Sleep方法可以让当前线程暂停一段时间,适合实现延时操作

          using System;
          using System.Threading;
          
          class Program
          {
              static void Main()
              {
                  for (int i = 0 i < 5; ++i)
                  {
                      Console.WriteLine($"Iteration {i + 1}");
                      Thread.Sleep(1000);
                  }
              }
          }
          

          Thread.Sleep会阻塞当前线程,因此它不适合在需要高并发的场景中使用,对于更复杂的异步操作,可以使用asyncawait