abp+dapper+mysql_ABP公共结构 – 时间与时区设置 - ABP 中文文档

2.6 ABP公共结构 – 时间与时区设置

2.6.1 简介

虽然有些应用的需求是单时区,然而另一些是需要对不同的时区进行处理的。为了满足这样的需求以及对时间的处理。ABP提供了处理时间操作的通用基础设施。

2.6.2 Clock

Clock 这个类是主要用来处理 DateTime 的值。它具有以下静态属性和方法:

Now :根据当前设置的提供器来获取当前时间

Kind :取得当前提供器的 DateTimeKind

SupportsMultipleTimezone :取得一个值用来判断该应用当前所使用的提供器是否支持多时区转换(只有ClockProviders.Utc才支持多时区之间的转换)

Normalize 对给定的时间使用当前提供器来进行转换

所以我们不应该使用 DateTime.Now,而是使用 Clock.Now,如下所示:

DateTime now = Clock.Now;

ABP中内置了3种Provider,如下所示:

ClockProviders.Unspecified (UnspecifiedClockProvider):这是默认的provider并且它的表现行为就像 DateTime.Now。

ClockProviders.Utc (UtcClockProvider): 它使用UTC时间,Clock.Now 等效于 DateTime.UtcNow。Normalize方法会将给定的时间转换为UTC时间并且设置它的Kind为 DateTimeKind.Utc。它支持多时区操作。

ClockProviders.Local (LocalClockProvider): 程序宿主的计算机时间。Normalize方法会将给定的时间转换为本地时间并且设置它的Kind为 DateTimeKind.Local。

为了支持多时区转换,你可以设置Clock.Provider为:

Clock.Provider = ClockProviders.Utc;

对于上面的设置,我们通常是在应用程序主入口就设置好了。例如:main函数,web应用的Application_Start函数。

2.6.3 Client Side

我们可以在客户端脚本中使用 abp.clock, 当你在服务器端设置好 Clock.Provider,ABP 会自动的在客户端设置好 abp.clockprovider。ABP创建了一个脚本对象:abp.timing.timeZoneInfo 它包含了当前用户所设置的时区信息。这个信息包含了Windows和IANA时区的id和一些额外的windows时区信息,详细请查看源码 TimingScriptManager 的GetUsersTimezoneScriptsAsync函数。使用这些信息可以将服务器的UTC时间转换为客户端需要显示的时间。

注意:在客户端进行时间转换,首先你得设置你的应用默认为Utc,并且每个用户可以设置自己的时区,这个默认是使用SettingManager来设置的。然后你可以使用monent的timezone插件将服务器端时间转换为本地时间。首先全局设置:moment.tz.setDefault(abp.timing.timeZoneInfo.iana.timeZoneId); 然后你通过动态API,或者WebAPI取得JSON后,将JSON中的时间如此转换: moment(item.creationTime).format(‘LLL’),或者可以这样: abp.timing.convertToUserTimezone(dateTime).format(); 前提是你要使用abp.moment.js。作者的文档写的也不是很好,这是我开发过程中结合源码补充的。如果要为每个用户设置不同的时区,最好是将时区信息保存到用户表,登录的时候保存到Claim中。那么在MVC中转换的时候我们就可以用到 TimezoneHelper.ConvertFromUtc 。详细可以见提问:https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1320。

如果使用用户表来保存每个用户的时区,最好是自定义一个AbpSession:

public interface ICustomAbpSession : IAbpSession

{

string TimezoneId { get; }

string ImpersonatorTimezoneId { get; }

string GetUsersTimezoneScript();

}

public class CustomAbpSession : ClaimsAbpSession, ICustomAbpSession

{

public CustomAbpSession(IMultiTenancyConfig multiTenancy) : base(multiTenancy)

{

}

public virtual string TimezoneId

{

get

{

var timezoneIdClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == CustomAbpClaimTypes.TimezoneId);

return string.IsNullOrEmpty(timezoneIdClaim?.Value) ? null : timezoneIdClaim.Value;

}

}

public virtual string ImpersonatorTimezoneId

{

get

{

var impersonatorTimezoneIdClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == CustomAbpClaimTypes.ImpersonatorTimezoneId);

return string.IsNullOrEmpty(impersonatorTimezoneIdClaim?.Value) ? null : impersonatorTimezoneIdClaim.Value;

}

}

//使用这个代码来重置 TimingScriptManager.cs 的GetUsersTimezoneScriptsAsync函数取得的脚本。

//当然需要在_Layout.cshtml 中调用这个方法,如果不想这样写,也可以继承ITimingScriptManager接口,重新实现它。

public virtual string GetUsersTimezoneScript()

{

if (!Clock.SupportsMultipleTimezone)

return string.Empty;

var timezoneId = TimezoneId;

var timezone = TimeZoneInfo.FindSystemTimeZoneById(timezoneId);

var timezoneInfo = " {" +

" windows: {" +

" timeZoneId: '" + timezoneId + "'," +

" baseUtcOffsetInMilliseconds: '" + timezone.BaseUtcOffset.TotalMilliseconds + "'," +

" currentUtcOffsetInMilliseconds: '" + timezone.GetUtcOffset(Clock.Now).TotalMilliseconds + "'," +

" isDaylightSavingTimeNow: '" + timezone.IsDaylightSavingTime(Clock.Now) + "'" +

" }," +

" iana: {" +

" timeZoneId:'" + TimezoneHelper.WindowsToIana(timezoneId) + "'" +

" }," +

" }";

return " abp.timing.timeZoneInfo = " + timezoneInfo;

}

}

2.6.4 时区

ABP定义了一个 Abp.Timing.TimeZone (常量:TimingSettingNames.TimeZone) 配置名,用来存储Host,Tenant和User所选择的时区。ABP假定设定的时区是一个有效的 Windows timezone name。ABP也定义了一个时区映射文件,将Windows时区转换为 IANA 时区,这是因为有些通用库所使用的是 IANA timezone id。为了支持多时区,必须使用 UtcClockProvider。如果使用 UtcClockProvider,那么所有的时间值将会以UTC时间进行存储,并且以UTC时间发送到客户端。那么在客户端我们能将UTC时间转换为客户所设置的时区。

注意: 我遇到过这样的问题,在Windows Server 2012 如果系统的时区是协调世界时(Coordinated Universal Time)。并且默认用户时区是系统时区时,TimeZoneInfo.FindSystemTimeZoneById(timezoneId),ABP中取得IANA时区会报异常。

2.6.5 Binders and Converters

ABP能自动normalize来自如MVC,WebAPI以及ASP.NET Core应用的时间,这是基于当前的ClockProvider的。

ABP能基于当前的ClockProvider自动normalize来自数据库的时间,当 EntityFramework 以及 NHibernate 模块被使用的时候。

如果 UtcClockProvider 被使用,所有的时间都会作为UTC时间存储在数据库。并且所有来自客户端的时间都会被当做UTC时间来接收除非被明确的指定为其他时区。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ABP 应用程序中,您可以使用 Dapper 和 Entity Framework Core 两种 ORM 工具之一,或者甚至可以同时使用它们来访问数据库。以下是如何在 ABP 应用程序中同时使用 Dapper 和 Entity Framework Core 的步骤: 1.添加 Dapper 和 Entity Framework Core 的依赖项 在您的 ABP 应用程序中,您需要添加 Dapper 和 Entity Framework Core 的依赖项。您可以通过 NuGet 包管理器或手动编辑项目文件添加这些依赖项。添加 Dapper 和 Entity Framework Core 的依赖项后,您需要在 `Startup.cs` 文件中配置它们。 2.配置 Dapper 和 Entity Framework Core 在 `Startup.cs` 文件中,您需要配置 Dapper 和 Entity Framework Core。以下是一个示例: ```csharp public void ConfigureServices(IServiceCollection services) { // Add Dapper services.AddScoped<IDbConnection>(x => new SqlConnection(Configuration.GetConnectionString("Default"))); // Add Entity Framework Core services.AddAbpDbContext<MyProjectDbContext>(options => { options.AddDefaultRepositories(includeAllEntities: true); }); } ``` 在上面的代码中,我们使用 `AddScoped` 方法将 `IDbConnection` 注册为一个服务,并指定使用 `SqlConnection` 类创建连接。然后,我们使用 `AddAbpDbContext` 方法将 `MyProjectDbContext` 注册为一个服务,并指定包含所有实体。 3.编写 Dapper 和 Entity Framework Core 的查询 在您的应用程序中,您可以使用 Dapper 和 Entity Framework Core 的查询来访问数据库。以下是一个示例: ```csharp public class MyService : ITransientDependency { private readonly IDbConnection _connection; private readonly IRepository<MyEntity> _repository; public MyService(IDbConnection connection, IRepository<MyEntity> repository) { _connection = connection; _repository = repository; } public async Task<MyEntity> GetEntity(int id) { // Use Dapper var entity = await _connection.QueryFirstOrDefaultAsync<MyEntity>("SELECT * FROM MyEntities WHERE Id = @Id", new { Id = id }); // Use Entity Framework Core entity = await _repository.GetAsync(id); return entity; } } ``` 在上面的代码中,我们注入 `IDbConnection` 和 `IRepository<MyEntity>`,并在 `GetEntity` 方法中使用它们来执行 Dapper 和 Entity Framework Core 的查询。 需要注意的是,使用 Dapper 和 Entity Framework Core 的查询时,您需要务必遵循正确的事务处理和连接管理方式,以确保应用程序的数据完整性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值