惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
P
Palo Alto Networks Blog
C
Cisco Blogs
The Hacker News
The Hacker News
T
Threatpost
S
Schneier on Security
K
Kaspersky official blog
Spread Privacy
Spread Privacy
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
NISL@THU
NISL@THU
量子位
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Google DeepMind News
Google DeepMind News
Security Latest
Security Latest
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
博客园 - 叶小钗
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
News and Events Feed by Topic
爱范儿
爱范儿
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Cisco Talos Blog
Cisco Talos Blog
GbyAI
GbyAI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
T
Tenable Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
Forbes - Security
Forbes - Security
博客园 - 三生石上(FineUI控件)
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News and Events Feed by Topic
V
V2EX
Webroot Blog
Webroot Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Blog — PlanetScale
Blog — PlanetScale
M
MIT News - Artificial intelligence
Scott Helme
Scott Helme
Simon Willison's Weblog
Simon Willison's Weblog
L
LangChain Blog
W
WeLiveSecurity
Cloudbric
Cloudbric

忘忧的小站

SqlServer高频面试题(持续更新251114) | 忘忧的小站 MySql入门:备份恢复与安全管理 | 忘忧的小站 MySql入门:高可用与架构设计 | 忘忧的小站 MySql入门:SQL编程与高级特性 | 忘忧的小站 MySql入门:性能优化与调优 | 忘忧的小站 MySql入门:MySQL数据类型与表设计 | 忘忧的小站 MySql入门:MySQL核心概念与架构解析 | 忘忧的小站 Redis配置文件及常用命令详解 | 忘忧的小站 Redis入门:总结与展望 | 忘忧的小站 Redis入门:进阶知识与运维管理 | 忘忧的小站 Redis入门:Redis在项目中的实战应用 | 忘忧的小站 Redis入门:Redis的持久化与高可用 | 忘忧的小站 Redis入门:玩转Redis五大核心数据结构 | 忘忧的小站 Redis入门:Redis核心概念与快速入门 | 忘忧的小站 Lucene.Net 分布式索引实现方案 | 忘忧的小站 Lucene.Net 入门和简单使用 | 忘忧的小站 JavaScript授权Gps,音频,视频踩坑 | 忘忧的小站 Abp.Zero框架升级 | 忘忧的小站 mysql每日自动备份数据 | 忘忧的小站
.Net7 针对Utc时区转换问题中间件 | 忘忧的小站
本文作者: 忘忧 · 2023-11-01 · via 忘忧的小站

发表于 | 分类于 .Net Core | 0 | 阅读次数 2817

为什么要存储UTC时间

存储UTC(协调世界时)时间是为了在跨时区和时间转换的情况下保持时间的一致性和准确性。以下是一些原因:

  1. 时区独立性:UTC时间是不受时区影响的,它是全球标准时间。通过存储UTC时间,可以避免在不同时区之间进行转换和处理,确保时间的一致性,无论用户位于何处。

  2. 跨时区应用:对于涉及跨时区操作的应用程序,使用UTC时间可以简化时间计算和比较。如果存储本地时间,可能会面临时区转换和夏令时变更等问题,导致时间计算不准确。

  3. 数据一致性:当多个系统或数据库需要共享时间信息时,使用UTC时间可以确保数据的一致性。不同系统和数据库可以根据需要将UTC时间转换为本地时间进行显示,以满足用户的需求,而不会引起数据不一致的问题。

  4. 日志和审计:在日志记录和审计方面,使用UTC时间可以提供统一的时间戳,使得跨系统和跨地点的日志可以进行准确的时间排序和比较。

  5. 时间计算的准确性:在进行时间计算、持续时间计算或时间间隔比较时,使用UTC时间可以避免由于夏令时等因素引起的时间偏移和不一致性,确保计算的准确性。

总之,存储UTC时间可以提供时间的一致性、跨时区操作的便利性以及数据的一致性,尤其适用于涉及多个时区的应用程序和系统。当需要进行时间转换或比较时,可以将UTC时间转换为本地时间进行显示,以满足最终用户的需求。

代码中实现

var dateTime = Datetime.UtcNow;

如果这样实现的话那么接口请求的时间和请求返回的时间都需要手动处理,这样不不够优雅的

如何处理

安装Newtonsoft.Json
增加DateTimeFilter.cs

public class DateTimeFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        var parameters = context.ActionArguments;
        foreach (var parameter in parameters)
        {
           
            if (parameter.Value is DateTime dateTime)
            {
                dateTime = dateTime.ToUniversalTime();
                context.ActionArguments[parameter.Key] = dateTime;
            }
        }
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
    }
}

增加DateTimeJsonConverter.cs

public class DateTimeJsonConverter : DateTimeConverterBase
{
    
    public DateTimeJsonConverter()
    {
    }
  
    
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {

        
        
        // 用户配置的时区 ,建议使用Redis 或者内存缓存
        var setting = "";
        if (setting.IsNullOrEmpty())
        {
            DateTime dateTime = (DateTime)value;
            writer.WriteValue(dateTime.ToLocalTime());
        }
        else
        {
            TimeZoneInfo targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById(setting);
            DateTime targetTime = TimeZoneInfo.ConvertTimeFromUtc((DateTime) value, targetTimeZone);
            writer.WriteValue(targetTime);
        }

    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        DateTime dateTime = (DateTime)reader.Value;
        return dateTime.ToUniversalTime();
    }
}

在Program.cs 中注册

builder.Services.AddControllers(o =>
{
        o.Filters.Add(typeof(DateTimeFilter));
}).AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    options.SerializerSettings.ContractResolver = new DefaultContractResolver();
    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
    options.SerializerSettings.Converters.Add(new StringEnumConverter());
    options.SerializerSettings.Converters.Add(new DateTimeJsonConverter());

})

DateTimeFilter 是针对以下接口入参形式

        [HttpGet("utc")]
        public IActionResult Utc(DateTime utc)
        {
            return Ok(utc);
        }

DateTimeJsonConverter 是捕获不到接口的参数,只能捕获入参对象,和返回对象

    public class MyClass
        {
            public DateTime Utc { get; set; }
            
            public MyClass1 MyClassx { get; set; }
            public class MyClass1
            {
                public DateTime Utc1 { get; set; }
            }
        }
        [HttpGet("utc")]
        public IActionResult Utc(MyClass utc)
        {
            return Ok(utc);
        }
        
        //获取所有时区
         [HttpGet("TimeZone")]
        public IActionResult List()
        {
            var list = TimeZoneInfo.GetSystemTimeZones();
            return Ok(list.Select(x =>
            {
                return new
                {
                    Id = x.Id,
                    DisplayName = x.DisplayName
                };
            }).ToList());
        }

这样就实现对传入参数和返回参数 DateTime 类型转UTC时间再转回当前时区的实现
ControllerServicesRepository就不用再处理Datetime 类型时区转换的代码了, 直接可以使用

  • 本文链接: /archives/183
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!