DateTime with Azure和一个JavaScript应用程序

本文关键字:一个 JavaScript 应用程序 with Azure DateTime | 更新日期: 2023-09-27 18:03:51

我讨厌约会。

因此,在我的JavaScript应用程序中,我将当前日期传递给我的c# Web API。我这样做,我希望你这样做:

var model = {
    plannedCollectionDate: new Date()
};

在我的c# Web API中,我直接将其保存到数据库。然后,当我有这一点,试图创建一个总结页面。它是这样做的:

// If we have some collections
if (collections != null && collections.Count > 0)
{
    // Get our collections
    due = collections.Where(m => m.PlannedCollectionDate.Date < DateTime.Today).ToList();
    today = collections.Where(m => m.PlannedCollectionDate.Date == DateTime.Today).ToList();
    expected = collections.Where(m => m.PlannedCollectionDate.Date == DateTime.Today.AddDays(1).Date).ToList();
    planned = collections.Where(m => m.PlannedCollectionDate.Date > DateTime.Today.AddDays(1).Date).ToList();
}

问题是,azure设置为美国时区,我的应用程序从英国运行。所以所有的日期都不正确,因此截止日期,今天,预计和计划都是错误的。

我需要做的是确保所有的日期使用相同的时区。我试图通过执行

保存到数据库时仅存储DateTime的日期部分
model.PlannedCollectionDate = date.Date;

但这也不起作用。这很难测试,因为当它在azure上运行时,我不能步进代码,但在我将日期存储为日期(即时间)之前,它将所有内容设置为23:00。

我想要的只是一个可以应用于任何项目的解决方案。如果我发送一个日期给我的应用程序,它应该把它转换成UTC并存储它,然后每当我做比较时,它应该做UTC比较,当我把日期返回给JavaScript应用程序时,它应该知道把它显示为本地日期时间。

有人能帮我吗?

<标题> 更新

让我再详细解释一下。我有一个CollectionRequestModel它看起来像这样:

public class CollectionRequestModel
{
    public int Id { get; set; }
    [Range(1, Int32.MaxValue)]
    public int CenterId { get; set; }
    public string Reference { get; set; }
    public string Description { get; set; }
    public string CustomerReference { get; set; }
    public string CustomerName { get; set; }
    public string CustomerBusinessName { get; set; }
    public string SupplierName { get; set; }
    [Required]
    public DateTime PlannedCollectionDate { get; set; }
    [Required]
    public CollectionStatusRequestModel Status { get; set; }
    public string CreatedById { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime? DeliveredDate { get; set; }
    public string ReceivedBy { get; set; }
    public string ReceivedBySignature { get; set; }
    public DateTime? CollectedDate { get; set; }
    public string CollectedBy { get; set; }
    public string CollectedBySignature { get; set; }
}

这是通过调用我的web api上的一个方法创建的,看起来像这样:

/// <summary>
/// Creates or updates the collection
/// </summary>
/// <param name="model">The collection which is to be saved</param>
/// <returns>The collection that was saved to the database</returns>
private async Task<IHttpActionResult> SaveAsync(CollectionRequestModel model)
{
    // If our ModelState is invalid, return a bad request
    if (!ModelState.IsValid)
        return BadRequest(ModelState);
    // Update our CreatedById
    model.CreatedById = User.Identity.GetUserId();
    // Create a holder for our collection
    var collection = new Web.Models.Collection();
    // If our model has an id
    if (model.Id > 0)
    {
        // Update our collection
        collection = await UpdateCollectionFromModelAsync(model);
    }
    else
    {
        // Create our collection
        collection = ModelFactory.Create(model);
    }
    // Save the changes
    this.service.Save(collection);
    // Save to our database
    await this.UnitOfWork.SaveChangesAsync();
    // Return the result
    return Ok(this.ModelFactory.Create(collection));
}

ModelFactory和UpdateCollectionFromModel不会重构数据。modelfactory看起来像这样:

/// <summary>
/// Creates a collection model from the binding model
/// </summary>
/// <param name="model">The binding model</param>
/// <returns>A collection</returns>
public Web.Models.Collection Create(CollectionRequestModel model)
{
    // Get our current user's id
    var date = DateTime.UtcNow;
    // Assign our binding model to a new model
    var collection = new Web.Models.Collection()
    {
        Id = model.Id,
        CenterId = model.CenterId,
        Reference = model.Reference,
        Description = model.Description,
        CustomerReference = model.CustomerReference,
        CustomerName = model.CustomerName,
        CustomerBusinessName = model.CustomerBusinessName,
        SupplierName = model.SupplierName,
        PlannedCollectionDate = model.PlannedCollectionDate.Date,
        Status = (CollectionStatus)model.Status.Id,
        DeliveredDate = model.DeliveredDate,
        ReceivedBy = model.ReceivedBy,
        ReceivedBySignature = model.ReceivedBySignature,
        CollectedDate = model.CollectedDate,
        CollectedBy = model.CollectedBy,
        CollectedBySignature = model.CollectedBySignature,
        CreatedById = model.CreatedById,
        DateCreated = date,
        ModifiedById = model.CreatedById,
        DateModified = date
    };
    // Return our collection
    return collection;
}

如您所见,我只是传递model.PlannedCollectionDate.Date,而没有尝试更改区域性或将其设置为UTC或其他。从我的JavaScript应用程序,我只是设置了plannedCollectionDate作为一个新的日期('24/08/2016')。如果我使用控制台,我可以看到发送的日期是这样的:

2016年8月25日星期四00:00:00 GMT+0100 (GMT夏令时)

当我在azure服务器上运行时,它被保存到数据库中为:

2016-08-23 00:00:00.000

是完全错误的。当我在本地或azure端编辑时,它们都返回23。所以问题是什么时候发送日期(看起来)。

DateTime with Azure和一个JavaScript应用程序

您需要以严格的ISO8601格式发送日期:

String s = myDate.ToString("s"); // example 2009-06-15T13:45:30

你可以把它解析成一个日期

DateTime d = DateTime.ParseExact(dateString,"s", System.Globalization.CultureInfo.InvariantCulture);

这属于对Matt Wilko的回答的评论,但我没有代表

以ISO格式传递JavaScript代码中的日期:

var model = {
    plannedCollectionDate: new Date().toISOString()
};

按原样在数据库中保存日期。

当你做比较时,我建议使用DateTimeOffset而不是DateTime,但这是一个不同的讨论。

最后,以ISO时间将日期传递给客户端。您的客户端代码应该负责将其转换为正确的时区。

var someISOFormattedDate = getDateFromWebAPI();
var localDate = new Date(someISOFormattedDate );

我已经用不同的方式来做这个建议,也许是错误的方式,但它似乎是工作的。

我创建了一个扩展方法:
public static class DateTimeExtensions
{
    /// <summary>
    /// Converts the date from the server time to the UK time
    /// </summary>
    /// <param name="dateTime">The datetime object to convert</param>
    /// <param name="timeZoneId">The timezone to convert to</param>
    /// <returns></returns>
    public static DateTimeOffset ToZoneTime(this DateTime dateTime, string timeZoneId = "GMT Standard Time")
    {          
        // Get the timezones
        var currentTimeZone = TimeZoneInfo.Local;
        var targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
        // Convert the supplied date into the new timezone specific date
        var actualDate = TimeZoneInfo.ConvertTime(dateTime, currentTimeZone, targetTimeZone);
        // Return our converted dateTime
        return actualDate;
    }
}

,当我创建或更新任何东西时,我这样做:

// Assign our binding model to a new model
var collection = new Web.Models.Collection()
{
    PlannedCollectionDate = model.PlannedCollectionDate.ToZoneTime().Date
};