如何将datetime解释为用户';Acumatica的本地时区

如何将datetime解释为用户';Acumatica的本地时区,acumatica,Acumatica,我们有一个按钮“开始”,它将DateStart字段填充到DateTime。现在 检索datetime时,它始终显示服务器的日期/时间,而不是用户的本地时区版本。如何使它像lastModifiedDateTime/CreatedDateTime一样工作,无论何时查看它,它都被格式化为用户的本地时区。我尝试了UseTimeZone=true/false,但没有任何效果 这是我不工作的代码 #region DateStarted public abstract class dateStarte

我们有一个按钮“开始”,它将DateStart字段填充到DateTime。现在

检索datetime时,它始终显示服务器的日期/时间,而不是用户的本地时区版本。如何使它像lastModifiedDateTime/CreatedDateTime一样工作,无论何时查看它,它都被格式化为用户的本地时区。我尝试了UseTimeZone=true/false,但没有任何效果

这是我不工作的代码

#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

源代码
屏幕SM204570中查找类
PXDBDateAndTime
的代码。出于调试目的,您可以复制整个属性并将其重命名为类似于
PXDBDateAndTimeDebug

通过这种方法,您可以调试
SetUseTimeZone
GetTimeZone
方法。使用的时区来自
LocaleInfo.GetTimeZone
方法,您也应该调试它:

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

    return PXTimeZoneInfo.Invariant;
}

这里的问题是,从您的问题中,我们无法判断Acumatica时区处理是否确实存在问题,或者您的实例中是否正确配置了用户配置文件时区,或者您期望的结果是否实际是由DotNet framework完成的有效ISO转换。一步一步地调试应该会显示发生了什么。

源代码
屏幕SM204570中查找类
PXDBDateAndTime
的代码。出于调试目的,您可以复制整个属性并将其重命名为类似于
PXDBDateAndTimeDebug

通过这种方法,您可以调试
SetUseTimeZone
GetTimeZone
方法。使用的时区来自
LocaleInfo.GetTimeZone
方法,您也应该调试它:

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

    return PXTimeZoneInfo.Invariant;
}

这里的问题是,从您的问题中,我们无法判断Acumatica时区处理是否确实存在问题,或者您的实例中是否正确配置了用户配置文件时区,或者您期望的结果是否实际是由DotNet framework完成的有效ISO转换。一步一步地调试应该会发现发生了什么。

在分析CreatedDateTime和LastModifiedDatetime以及其他日期的行为如何相同后,问题在于输入。因此,我创建了以下代码来保存关于当前用户时区的正确日期时间

 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;
    }
}
以及实施:

  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();
    }
公共PXAction开始按钮;
[PXUIField(DisplayName=“Start”,Visible=true)]
[PXButton()]
公共虚拟void开始按钮()
{
如果(Document.Current!=null)
{
CQLMChecklists doc=文件。当前;
操作。按Save();
开始检查列表(DateTimeHelper.Now(),DateTimeHelper.Now().Value,ref doc);
文件更新(doc);
}
操作。按Save();
}

在分析CreatedDateTime和LastModifiedDatetime以及其他日期如何表现相同后,问题在于输入。因此,我创建了以下代码来保存关于当前用户时区的正确日期时间

 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;
    }
}
以及实施:

  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();
    }
公共PXAction开始按钮;
[PXUIField(DisplayName=“Start”,Visible=true)]
[PXButton()]
公共虚拟void开始按钮()
{
如果(Document.Current!=null)
{
CQLMChecklists doc=文件。当前;
操作。按Save();
开始检查列表(DateTimeHelper.Now(),DateTimeHelper.Now().Value,ref doc);
文件更新(doc);
}
操作。按Save();
}

听起来就像只使用
PX.Common.PXTimeZoneInfo。现在
就足以完成这项工作了


PX.Common.PXTimeZoneInfo
也有
UtcNow
UtcToday
,和
今天
,如果需要的话

听起来就像只使用
PX.Common.PXTimeZoneInfo。现在
就足以完成这项工作了


PX.Common.PXTimeZoneInfo
还有
UtcNow
UtcToday
,以及
今天
如果需要

我注意到,在某些配置中,显示的值是本地时间,但作为UTC时间存储在数据库中。此外,如果用户没有设置时区,我认为它将使用服务器时区。只是一些想法。也可以尝试使用PX.Common.PXTimeZoneInfo.Now vs DateTime.Now来查看是否在用户时区中。是否可能要启动的字段设置不正确?我以前也遇到过类似的问题-我必须找到我使用的配置,但为了获得现在的时间,我总是使用PX.Common.PXTimeZoneInfo.Now。我还认为用户时区配置与预期的区域设置不匹配。如果没有时区配置,它应该默认为PXTimeZoneInfo.Invariant GMT 0000(根据源代码)。我注意到,在某些配置中,显示的值是本地时间,但作为UTC时间存储在数据库中。此外,如果用户没有设置时区,我认为它将使用服务器时区。只是一些想法。也可以尝试使用PX.Common.PXTimeZoneInfo.Now vs DateTime.Now来查看是否在用户时区中。是否可能要启动的字段设置不正确?我以前也遇到过类似的问题-我必须找到我使用的配置,但为了获得现在的时间,我总是使用PX.Common.PXTimeZoneInfo.Now。我还认为用户时区配置与预期的区域设置不匹配。如果没有时区配置,它应该默认为PXTimeZoneInfo.Unvariable GMT 0000(根据源代码)。您是否尝试了PX.Common.PXTimeZoneInfo.Now,它看起来与您的Now方法类似?嗨,Brendan,是的,这是正确的。我会用的。谢谢。你试过PX.Common.PXTimeZoneInfo.Now了吗?它看起来和你的Now方法类似。嗨,Brendan,是的,没错。我会用的。谢谢