FLEX:处理时区偏移

发布于 2024-11-17 06:39:27 字数 307 浏览 1 评论 0原文

我开发了一个用于分布式数据管理的 FLEX 应用程序。当我们的亚洲员工指定日期时,该日期将被保存 +1 天。

如果我检查我的时区偏移量,它是 +60,它们的偏移量是 +520。

var dNow:Date = new Date();
    trace("Your time zone offset: " + dNow.getTimezoneOffset() + " minutes");

我认为这就是问题所在?如果是这样,您是否建议我将输入的日期修正 460 分钟,然后再将其发送到我们的服务器进行保存?怎么做呢?

I've developed an FLEX application for distributed data administration. When our Asian employees specify a date, it will be saved +1 day.

If I check my timezone offset it is +60, their offset is +520.

var dNow:Date = new Date();
    trace("Your time zone offset: " + dNow.getTimezoneOffset() + " minutes");

I assume this is the problem? If so, would you suggest that I correct the entered date by 460 minutes before sending it to our server for saving? How to do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断桥再见 2024-11-24 06:39:27

当您在 ActionScript 中创建 Date 对象时,它将在内部将其值存储在与时区无关的 UTC 数值中,但是将根据客户端的本地时区/夏令时偏移量应用更正来计算该值。 Flash通过底层操作系统获取当前时区,目前无法设置自定义时区。

因此,除非您恰好处于 UTC+0 情况,否则日期的实际值将包含一定数量的小时/分钟的偏移量。

当再次显示相同的日期时,默认格式化程序和标准 Flex 控件会将日期转换回本地时区:当在同一台计算机(或具有相同时区偏移的计算机)上执行这两个操作时,这些更正将进行补偿对于彼此,你根本不会注意到这种行为。

但是,如果您不准备处理它们,则存储该值(例如,将其发送到 BlazeDS/LCDS 以将其保存在数据库中)并从具有不同时区的客户端检索它可能会产生意想不到的效果:例如,如果两个客户端的时区修正之间的差异为负数(例如,-1 小时),输入为 28/06/2011 的一天可以在 DateField 组件中显示为 27/06/2011。

这是一个复杂的问题,并且没有快速简单的解决方案:这取决于您想要提供的时区支持的类型。

最简单的解决方案是将所有客户端设置为使用公共时区,例如服务器的时区。不幸的是,当前版本的 Flash Player 不允许指定显式时区,要实现此策略,您需要在将 Flex 组件创建的任何日期发送到服务器之前手动设置内部 UTC 值,以补偿本地时区偏移。另一种常见的解决方法是避免使用 Date 对象并使用 ISO 字符串表示形式来表示日期。

您可以在 Adob​​e Bug Tracker 中找到大量信息(以及一些有关时区管理的想法),请参阅 https://bugs.adobe.com/jira/browse/FP-175 问题,标题为“在 flashplayer 上设置特定时区,这将使应用程序能够在不同时区的所有客户端上保持相同的时区。”

When you create a Date object in ActionScript, it will internally store its value in a timezione-free UTC numeric value, however this value will be calculated applying a correction due to the local timezone/daylight savings offset of the client. Flash obtain the current timezone by the underlying operating system, and currently there's no way to set a custom timezone.

So, unless you are exactly in a UTC+0 situation, the actual value of the Date will contain an offset of a certain number of hours/minuts.

When displaying the same date again, the default formatters and the standard Flex controls will convert back the Date to the local timezone: when the two operations are performed on the same machine (or on machines with the same timezone offset), those corrections will compensate for each other, and you won't notice this behavior at all.

However, storing that value (for example, sending it to BlazeDS/LCDS to save it in a DB) and retrieving it from a client with a different timezone can produce unexpected effect, if you are not prepared to handle them: for example, if the difference between the timezone corrections of the two clients is negative (for example, -1 hours) a day entered as 28/06/2011 can be displayed as 27/06/2011 in a DateField component.

It is a complex problem, and there's no quick and easy solution: it dependes on the type of timezone support you want to provide.

The simplest solution would be setting all clients to work with a common timezone, for example the timezone of the server. Unfortunately, the current version of the Flash Player doesn't allow to specify an explicit timezone, and to implement this strategy you need to manually set the internal UTC values of any Date created by Flex components before sending it to the server, to compensate the local timezone offset. Another common workaround is avoiding using Date objects and using ISO string representation for dates.

You can find a lot of information (and some ideas about timezone management) in the Adobe Bug Tracker, see the https://bugs.adobe.com/jira/browse/FP-175 issue, with title "Set specific timezone on flashplayer. This would enable applications to keep same timezone on all clients in different timezones."

眼藏柔 2024-11-24 06:39:27

最后,我实现了这个解决方案:

获取从服务器作为 ISO 字符串的数据(冷融合到 MS SQL Server):

SELECT CONVERT(varchar, CONTRACTED_DELIVERY, 104) AS CONTRACTED_DELIVERY
FROM (...)
WHERe (...)

然后在接收它时,我将其转换为 ValueObject(遵循 Cairngorm 框架) :

            if (obj.CONTRACTED_DELIVERY != null){
            this.CONTRACTED_DELIVERY = DateField.stringToDate(obj.CONTRACTED_DELIVERY,"DD.MM.YYYY");
        }else{
            this.CONTRACTED_DELIVERY = obj.CONTRACTED_DELIVERY;
        }

将日期作为 ISO 字符串发送到服务器:

UPDATE (...)
SET CONTRACTED_DELIVERY = <cfif productionDetails.CONTRACTED_DELIVERY EQ ''>null<cfelse>'#dateFormat(productionDetails.CONTRACTED_DELIVERY,"YYYY-MM-DD")#'</cfif>
WHERE (...)

请随时询问其他信息!

Finally I've implemented this solution:

get the data from the server as ISO String (with coldfusion to a MS SQL Server):

SELECT CONVERT(varchar, CONTRACTED_DELIVERY, 104) AS CONTRACTED_DELIVERY
FROM (...)
WHERe (...)

then when receiving it I convert it in the ValueObject (following the Cairngorm framework):

            if (obj.CONTRACTED_DELIVERY != null){
            this.CONTRACTED_DELIVERY = DateField.stringToDate(obj.CONTRACTED_DELIVERY,"DD.MM.YYYY");
        }else{
            this.CONTRACTED_DELIVERY = obj.CONTRACTED_DELIVERY;
        }

to send the date to the server as ISO String:

UPDATE (...)
SET CONTRACTED_DELIVERY = <cfif productionDetails.CONTRACTED_DELIVERY EQ ''>null<cfelse>'#dateFormat(productionDetails.CONTRACTED_DELIVERY,"YYYY-MM-DD")#'</cfif>
WHERE (...)

Feel free to ask for additional information!

如果没结果 2024-11-24 06:39:27

基于 https://forums.adobe.com/thread/1076594:

services-config.xml

<service id="myProxyBootstrapService" class="org.myapp.flex.proxy.MyProxyBootstrapService"/> 

MyProxyBootstrapService.java

MyProxyBootstrapService extends AbstractBootstrapService {

@Override
public void initialize(String arg0, ConfigMap arg1) {
    PropertyProxyRegistry registry = PropertyProxyRegistry.getRegistry();
    registry.register(Serializable.class, new DateProxy());
}

DateProxy.java

public class DateProxy extends BeanProxy {

private static final long serialVersionUID = 8097540028987261941L;

private Integer serverOffset;

public DateProxy() {
    super();
}

@Override
public Object getValue(Object instance, String propertyName) {
    Object result = super.getValue(instance, propertyName);
    if (result instanceof Date) {
        result = toDate(result, true);  
    }
    return result;
}

@Override
public void setValue(Object object, String propertyName, Object value) {
    if (value instanceof Date) {
        Date date = toDate(value, false);
        super.setValue(object, propertyName, date);
    } else {
        super.setValue(object, propertyName, value);
    }
}

private Date toDate(Object value, Boolean serverToClient) {
    Date date = (Date) value;
    Integer clientOffset = getClientOffset();
    Integer serverOffset = getServerOffset();
    if (clientOffset != null && !clientOffset.equals(serverOffset)) {
        Calendar cal = new GregorianCalendar(TimeZone.getDefault());  
        cal.setTime(date);  
        cal.add(Calendar.MINUTE, serverToClient ? clientOffset - serverOffset : serverOffset - clientOffset);  
        date.setTime(cal.getTimeInMillis());
    }
    return date;
}

private Integer getClientOffset() {
    return (Integer) FlexContext.getFlexSession().getAttribute("TIMEZONE_FLEX_OFFSET");
}

private Integer getServerOffset() {
    if (serverOffset == null) {
        serverOffset = Calendar.getInstance().getTimeZone().getOffset(new Date().getTime()) / 1000 / 60 * -1;
    }
    return serverOffset;
}

a Blaze DS / Adobe LiveCycle DS solution based on https://forums.adobe.com/thread/1076594:

services-config.xml

<service id="myProxyBootstrapService" class="org.myapp.flex.proxy.MyProxyBootstrapService"/> 

MyProxyBootstrapService.java

MyProxyBootstrapService extends AbstractBootstrapService {

@Override
public void initialize(String arg0, ConfigMap arg1) {
    PropertyProxyRegistry registry = PropertyProxyRegistry.getRegistry();
    registry.register(Serializable.class, new DateProxy());
}

DateProxy.java

public class DateProxy extends BeanProxy {

private static final long serialVersionUID = 8097540028987261941L;

private Integer serverOffset;

public DateProxy() {
    super();
}

@Override
public Object getValue(Object instance, String propertyName) {
    Object result = super.getValue(instance, propertyName);
    if (result instanceof Date) {
        result = toDate(result, true);  
    }
    return result;
}

@Override
public void setValue(Object object, String propertyName, Object value) {
    if (value instanceof Date) {
        Date date = toDate(value, false);
        super.setValue(object, propertyName, date);
    } else {
        super.setValue(object, propertyName, value);
    }
}

private Date toDate(Object value, Boolean serverToClient) {
    Date date = (Date) value;
    Integer clientOffset = getClientOffset();
    Integer serverOffset = getServerOffset();
    if (clientOffset != null && !clientOffset.equals(serverOffset)) {
        Calendar cal = new GregorianCalendar(TimeZone.getDefault());  
        cal.setTime(date);  
        cal.add(Calendar.MINUTE, serverToClient ? clientOffset - serverOffset : serverOffset - clientOffset);  
        date.setTime(cal.getTimeInMillis());
    }
    return date;
}

private Integer getClientOffset() {
    return (Integer) FlexContext.getFlexSession().getAttribute("TIMEZONE_FLEX_OFFSET");
}

private Integer getServerOffset() {
    if (serverOffset == null) {
        serverOffset = Calendar.getInstance().getTimeZone().getOffset(new Date().getTime()) / 1000 / 60 * -1;
    }
    return serverOffset;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文