How to interpret datetime as User's local time

2019-08-20 03:54发布

问题:

We have a button "Start" that populates the dateStarted field to DateTime.Now..

When retrieving datetime, it always shows the server's date/time instead of user's local timezone version. How do i make it work like lastModifiedDateTime/CreatedDateTime that whenever we view it it's formatted as user's local timezone. I tried UseTimeZone = true/false but nothing is working

Here is my code that is not working

#region DateStarted
    public abstract class dateStarted : PX.Data.IBqlField
    {
    }
    protected DateTime? _DateStarted;
    [PXDBDateAndTime(DisplayNameDate = "Date Started", DisplayNameTime = "Time", UseTimeZone = true)]

    public virtual DateTime? DateStarted
    {
        get
        {
            return this._DateStarted;
        }
        set
        {
            this._DateStarted = value;
        }
    }
    #endregion

回答1:

It sounds like just using PX.Common.PXTimeZoneInfo.Now is enough to do the job.

PX.Common.PXTimeZoneInfo also has UtcNow, UtcToday, and Today if needed



回答2:

Look up the code of class PXDBDateAndTime in Source Code screen SM204570. For debugging purpose you can copy the whole attribute and rename it to something else like PXDBDateAndTimeDebug:

[PXDBDateAndTimeDebug(DisplayNameDate = "Date Started", DisplayNameTime = "Time", UseTimeZone = true)]

With that approach you can debug SetUseTimeZone and GetTimeZone methods. The time zone used is coming from LocaleInfo.GetTimeZone method and you should debug that too:

public static PXTimeZoneInfo GetTimeZone()
{
    if (!PXContext.PXIdentity.IsAnonymous() && PXContext.PXIdentity.TimeZone != null)
    {
        return PXContext.PXIdentity.TimeZone;
    }

    return PXTimeZoneInfo.Invariant;
}

The issue here is that from your question we can't tell if there's actually a problem with Acumatica time zone handling or if the user profile time zone is properly configured in your instance or if the result you're expecting is actually a valid ISO conversion as done by the DotNet framework. Debugging step by step should reveal what's going on.



回答3:

After analyzing how CreatedDateTime and LastModifiedDatetime and other dates behave the same, the problem is in the input. So i created the following code to save the correct datetime with regards to the current user's timezone.

 public static class DateTimeHelper
{
    public static DateTime? Now()
    {
        var test = LocaleInfo.GetTimeZone();
        PXTimeZoneInfo timezone = LocaleInfo.GetTimeZone();
        DateTime dt = DateTime.UtcNow;
        dt = PXTimeZoneInfo.ConvertTimeFromUtc(dt, timezone);
        return dt;
    }
}

and the implementation:

  public PXAction<CQLMChecklists> startButton;
    [PXUIField(DisplayName = "Start", Visible = true)]
    [PXButton()]
    public virtual void StartButton()
    {
        if (Document.Current != null)
        {
            CQLMChecklists doc = Document.Current;

            Actions.PressSave();


            CommenceChecklist(DateTimeHelper.Now(), DateTimeHelper.Now().Value, ref doc);
            Document.Update(doc);
        }
        Actions.PressSave();
    }


标签: acumatica