应该使用哪种Noda Time类型来计算特定日期和今天之间的年/月/日?

时间:2015-08-10 21:12:53

标签: c# .net nodatime

我正在构建一个应用程序,需要计算“两个日期之间有多少个星期/几个月/几年”以及我所有用户来自单个时区的内容。

我想知道,为此更好地使用SELECT DcProd.Title, EfProd.Name, DcProd.Summary, DcProd.Product, EfProd.ProductStatus, EfProd.ViewOnlyLicenses, EfProd.FullLicenses, DcProd.Advertise, EfProd.CustomerAccount_Id, DcPageRelation.url_name_, CASE WHEN DcProd.ProductType = 1 THEN 'Module' WHEN DcProd.ProductType = 2 THEN 'Portal Add-On' WHEN DcProd.ProductType = 3 THEN 'Language' WHEN DcProd.ProductType = 4 THEN 'Jumpstart' WHEN DcProd.ProductType = 5 THEN 'Documents Connector' WHEN DcProd.ProductType = 6 THEN 'Documents Add-On' WHEN DcProd.ProductType = 7 THEN 'Express' WHEN DcProd.ProductType = 8 THEN 'Process Add-On' WHEN DcProd.ProductType = 9 THEN 'Process Solution' WHEN DcProd.ProductType = 10 THEN 'Training Add-On' ELSE null END AS ProdType, (SELECT DcRelation2.child_item_additional_info FROM [MC_Sitefinity].[dbo].[sf_dynamic_content] AS DcStatus2 LEFT JOIN [MC_Sitefinity].[dbo].[sf_content_link] AS DcRelation2 ON DcStatus2.original_content_id = DcRelation2.parent_item_id AND DcRelation2.component_property_name='Image' WHERE DcProd.base_id= DcStatus2.base_id) as theimage FROM [MC_Sitefinity].[dbo].[mastercontrolproducts_mastercontrolproduct] AS DcProd LEFT JOIN [MasterControlSitefinity].[dbo].[ProductLicense] AS EfProd ON DcProd.Product = EfProd.Product_Id AND EfProd.CustomerAccount_Id = @CustomerId --matching dynamic content (Dc) products to Entity Framework (Ef) products LEFT JOIN [MC_Sitefinity].[dbo].[sf_dynamic_content] AS DcStatus ON DcProd.base_id = DcStatus.base_id -- show only published and visible. LEFT JOIN [MC_Sitefinity].[dbo].[sf_content_link] AS DcRelation ON DcStatus.original_content_id = DcRelation.parent_item_id AND DcRelation.component_property_name = 'ProductPageUrl' --Gets related items for page url LEFT JOIN [MC_Sitefinity].[dbo].[sf_page_node] AS DcPageRelation ON DcRelation.child_item_id = DcPageRelation.id --gets page url for query WHERE DcStatus.visible = 1 AND DcStatus.approval_workflow_state_ = 'Published' ORDER BY ProdType (因为我只使用一个时区)或LocalDateTime(考虑可能的DST和偏移量变化)?

另外,我在做

时是对的
ZonedDateTime

1 个答案:

答案 0 :(得分:3)

对于第一种方案,请使用LocalDate类型以及Period.Between方法。

对于第二种情况,你可以构建一个类似的LocalDateTime,但结果值将反映“UTC日” - 这是一个人工构造。

每当你需要“现在”时:

  1. IClock实施开始,例如SystemClock.Instance
  2. 通过时钟呼叫Instant获取.Now
  3. 确定您希望“现在”反映的时区。使用.InZone即时投影到该区域中的ZonedDateTime
  4. 从那里,拆分您需要的任何组件以满足您正在使用的场景。例如,您可以致电.Date以获取LocalDate个实例,以便与您询问的第一个方案一起使用。
  5. 一般情况下,尽量避免调用DateTime.NowDateTime.UtcNow。当然,有些地方你可以用它来进行短切,但API不一定会引导你得出正确的结论。

    总结两种情况:

    // assuming you start with a DateTime, perhaps from a db.
    DateTime dt = new DateTime(2016,1,1);
    LocalDate ldt = LocalDateTime.FromDateTime(dt).Date;
    
    DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
    ZonedDateTime now = SystemClock.Instance.Now.InZone(tz);
    LocalDate today = now.Date;
    
    Period period = Period.Between(today, ldt, PeriodUnits.YearMonthDay);
    
    int years = (int) period.Years;
    int months = (int) period.Months;
    int days = (int) period.Days;
    

    另外,请注意在Noda Time 2.0(目前处于alpha版本)中,它有点简单:

    DateTime dt = new DateTime(2016, 1, 1);
    LocalDate ldt = LocalDate.FromDateTime(dt); // 2.0
    
    DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
    LocalDate today = SystemClock.Instance.InZone(tz).GetCurrentDate();  // 2.0
    
    Period period = Period.Between(today, ldt, PeriodUnits.YearMonthDay);
    
    int years = (int)period.Years;
    int months = (int)period.Months;
    int days = (int)period.Days;