我正在尝试学习如何在我的应用程序中使用 NodaTime,但找不到很多关于如何使用此库执行某些操作的示例。
鉴于:
"2012/08/30 17:45:00""yyyy/MM/dd HH:mm:ss"-5我如何用 NodaTime 解析它以获得
OffsetDateTime?Instant?我正在使用最新版本的NodaTime和Mongo DB官方驱动程序.我有一个简单的POCO类,它使用NodaTime ZonedDateTime作为一些属性中.NET DateTime的替代品.
public class MyPOCO
{
[BsonId]
[Key]
public ObjectId SomeId { get; set; }
public string SomeProperty { get; set; }
public ZonedDateTime SomeDateTime { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我可以轻松地将Model放入集合中,但是当我尝试读取查询的模型时,我得到以下内容MongoDB.Bson.BsonSerializationException:
值类NodaTime.ZonedDateTime无法反序列化
什么是解决/解决这个问题的好或最佳做法?
UPDATE
在发布我的问题解决方案后,我面临一个可能的新问题......当我查询集合并在我的查询中使用DateTime时,就像where SomeDateTime < now' (where现在is a variable I create from system time) it seems that each document must be deserialized using myZonedDateTimeSerializer`可以在where子句之前进行评估.这看起来像是一个很大的性能问题,不是吗?我真的要考虑再次回到BCL DateTime,即使它会受到伤害.
更新2
我正在接受我的解决方案ZonedDateTimeSerializer,但我对NodaTime与MongoDB的结合感到不舒服,而两者都是很好的个性化解决方案.但是他们目前在没有大量操纵的情况下一起工作得不好.
我们正在实现 PostgreSQL,并决定使用 NodaTime 代替标准 .NET DateTime。PostgreSQL 有一个“带有时区的时间戳”类型,NodaTime 通过 SystemClock.Instance.Now 方法返回带有时区的日期和时间值。但是,SystemClock.Instance.Now (2015-07-17T13:22:52Z) 返回的值不能直接写入 PostgreSQL 字段。是否有处理 NodaTime/PostgreSQL 实现的最佳实践?
我们如何在特定时区创建日期/时间并输出与UTC偏移的短ISO 8601日期/时间?例如,2015年9月8日下午5点太平洋标准时间必须如下所示:
2015-09-08T17:00:00-07:00
Run Code Online (Sandbox Code Playgroud)
这是我目前的尝试.
using System;
using NodaTime;
using NodaTime.Text;
namespace ConsoleApplication1_Nodatime
{
class Program
{
public static void Log(string x) => Console.WriteLine(x);
public static void Read() => Console.ReadLine();
static void Main(string[] args)
{
var localDateTime = new LocalDateTime(2015, 09, 08, 17, 0);
var zone = DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/Vancouver");
var zonedDateTime = localDateTime.InZoneStrictly(zone);
Log(zonedDateTime.ToOffsetDateTime().ToString());
Read();
}
}
}
Run Code Online (Sandbox Code Playgroud)
虽然看似太多步骤,但这种方法很有效.
LocalDateTimeDateTimeZoneLocalDateTime为aZonedDateTimeZonedDateTime为OffsetDateTime我们如何用更少的步骤来做到这一点?
var easternTimeZone = DateTimeZoneProviders.Tzdb[timeZoneIdentifier];
Run Code Online (Sandbox Code Playgroud)
使用 NodaTime 我应该如何验证当字符串 timeZoneIdentifier 设置为有效的 IANA 字符串(如“Europe/Stockholm”)时,它被视为有效但不支持的 IANA 字符串被拒绝。
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
解析"下午1:15"很容易:
var pattern = LocalTimePattern.CreateWithInvariantCulture("h:mm tt");
var time = pattern.Parse("1:15 pm").Value;
Run Code Online (Sandbox Code Playgroud)
但是,这不适用于"1:15 PM","1:15 PM"或"1:15 pm"的类似表格
是否内置支持其他形式的am/pm说明符,还是需要使用字符串预处理进行处理?
我一直在使用以下代码而没有缺陷:
internal static string WindowsToIana(string windowsZoneId)
{
if (windowsZoneId.Equals("UTC", StringComparison.Ordinal))
return "Etc/UTC";
var tzdbSource = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default;
var tzi = TimeZoneInfo.FindSystemTimeZoneById(windowsZoneId);
if (tzi == null) return null;
var tzid = tzdbSource.MapTimeZoneId(tzi);
if (tzid == null) return null;
return tzdbSource.CanonicalIdMap[tzid];
}
Run Code Online (Sandbox Code Playgroud)
将NodaTime升级到2.0版时,我现在得到一个编译时错误,说MapTimeZoneId不再存在.如何让这个功能再次运行?
我有一些LocalDateTimes 需要根据定义的分钟列表将一天中的时间向上/向下舍入到最接近的分钟数。例如,如果我有日期时间2018-03-20T12:13:47并且我必须将它四舍五入到下一个半小时(所以分钟是 00 或 30),我会得到2018-03-20T12:30:00. 四舍五入会给2018-03-20T12:00:00.
四舍五入可以是任意分钟,例如每 10 分钟 (0, 10, 20, 30, 40, 50),每刻钟 (0, 15, 30, 45),或者说到四分之一或之后 (15 , 45)。这意味着四舍五入的日期可能会在另一个日期结束。
NodaTime 中是否有任何功能可以帮助进行此四舍五入,还是我必须自己编写?我现在有一个工作版本,但它包括双循环和向午夜添加小时和分钟。
当我看看如何将时间转换为NodaTime时,我发现很多帖子,但没有直接回答我需要什么.
我有:
- A DateTime object (DateTime myDateTime)
- An Olson timezone (var TZ = "America/Los_Angeles")
Run Code Online (Sandbox Code Playgroud)
我想要:
- A ZonedDateTime object (ZonedDateTime myZonedDateTime)
Run Code Online (Sandbox Code Playgroud)
理想情况下,我正在寻找一些帮助:
var myZonedDateTime = ZonedDateTime.From(myDateTime, TZ);
Run Code Online (Sandbox Code Playgroud)
但我看到的所有样本都将日期转换为字符串然后解析字符串,这看起来很奇怪.
有一个ZonedDateTime.FromDateTimeOffset()方法,但偏移量和TimeZone是不同的东西,因为TZ可以处理夏令时.
目前,我正在尝试使用JsonFormatters序列化ISO 8601规范中的字符串.在我的启动配置中格式化,但无法使其工作.
我的启动配置如下:
services.AddMvcCore(
(options) => {
options.SslPort = 44321;
options.Filters.Add(new RequireHttpsAttribute());
}
)
.AddJsonFormatters(jsonSerializerSettings => {
jsonSerializerSettings.DateParseHandling = DateParseHandling.None;
jsonSerializerSettings.DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffZ";
})
.AddApiExplorer()
.AddJsonOptions(options => {
options.AllowInputFormatterExceptionMessages = false;
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
Run Code Online (Sandbox Code Playgroud)
我也尝试过文档中提到的ServiceStackText,但这也没有用.
NodaSerializerDefinitions.LocalTimeSerializer.ConfigureSerializer();
DateTimeZoneProviders.Tzdb
.CreateDefaultSerializersForNodaTime()
.ConfigureSerializersForNodaTime();
Run Code Online (Sandbox Code Playgroud)
我一直得到以下格式,
即LocalDate序列化:
{
"patientDob": "Thursday, June 15, 2017",
}
Run Code Online (Sandbox Code Playgroud)
如何配置字符串ISO 8601规范.NodaTime全局格式化日期类型?
我的模特,
{
public LocalDate patientDob { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和我的视图模型/ API资源: …