切换时区进行计算

2024-01-19

我们的应用程序将所有日期存储为 UTC 时区。然而,我们的主要业务部门位于“欧洲/柏林”时区(+2、+1,具体取决于夏令时)。因此,当我们确定某个时间跨度应等于哪个“月”时,我们希望使用该时区。

IE。开始时给出的时间段Thursday, 31 October 2013, 23:00:0 UTC并结束Friday, 29 November 2013, 23:00:00 UTC应该被全球称为Nov 13,至于我们的主要业务部门,泰晤士报将是Friday, 1 November 2013, 00:00:00 to Friday, 30 November 2013, 00:00:00

服务器本身以 UTC 运行,因此我们必须在计算周期名称时切换时区。我们在后端使用 Joda Datetime,我总是可以执行以下操作:

DateTime now = new DateTime();
now.withZone(DateTimeZone.forID("Europe/Berlin"));

然而,有很多计算正在进行,我想知道是否有更好的方法,在某个时区内进行所有计算?

如果它是一个独立的应用程序,可以使用类似的东西:

DateTimeZone old = DateTimeZone.getDefault();
DateTimeZone.setDefault(DateTimeZone.forID("Europe/Berlin"));

//do all work

DateTimeZone.setDefault(old);

然而,由于它是服务器环境,修改默认时区可能会导致其他线程上发生的其他计算出现错误结果。

所以,我想知道,java中是否有类似c#的using指令?除了错误的语法之外,我正在寻找这样的东西:

using(DateTimeZone.forID("Europe/Berlin")){
   //do all work, where JUST all DateTime usings inside this using
   //Statement are affected
}

编辑:一些小测试显示了问题:即使在 2 个线程上运行,两个线程中也会使用“默认”时区。因此,无论最后设置什么时区,都将用于两个线程。 (当然,这就是“默认”时区的用途。)

@Test
    public final void testTimeZoneThreaded() {

        Thread EuropeThread = new Thread(new Runnable() {
            @Override
            public void run() {
                DateTimeZone.setDefault(DateTimeZone.forID("Europe/Berlin"));

                int i = 0;
                while (i++ < 10) {
                    DateTime now = new DateTime();
                    System.out.println("It is now " + now + " in TimeZone " + DateTimeZone.getDefault().toString());

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        });

        Thread UTCThread = new Thread(new Runnable() {
            @Override
            public void run() {
                DateTimeZone.setDefault(DateTimeZone.forID("UTC"));

                int i = 0;
                while (i++ < 10) {
                    DateTime now = new DateTime();
                    System.out.println("It is now " + now + " in TimeZone " + DateTimeZone.getDefault().toString());

                    try {
                        Thread.sleep(800);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        });

        EuropeThread.start();
        UTCThread.start();

        while (UTCThread.isAlive()) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {

            }
        }

    }

能够在不同线程上使用不同的默认值也会有所帮助。

另一个想法是扩展 JodaDateTime 并使用其所有重载重写 to string() 方法:

class MyDateTime extends DateTime{
  @Override
  public String toString(){
    return super().withZone(DateTimeZone.for("Europe/Berlin")).toString();
  }

  @Override
  public String toString(String format){
    return super().withZone(DateTimeZone.for("Europe/Berlin")).toString(format);
  }
}
  • 日期时间是“最终”...:-(

因此,目前在生成期间名称(年、夸脱、月、周……)时,我总是需要手动处理它

public String getMonthPeriodName() {
        DateTime firstOfMonth = this.getPeriodStart().withZone(DateTimeZone.forID("Europe/Berlin")).dayOfMonth().withMinimumValue().millisOfDay().withMinimumValue();
    DateTime lastOfMonth = this.getPeriodEnd().withZone(DateTimeZone.forID("Europe/Berlin")).dayOfMonth().withMaximumValue().millisOfDay().withMaximumValue();

        if (firstOfMonth.isEqual(getPeriodStart()) && lastOfMonth.isEqual(getPeriodEnd())) {
            // full month.
            return firstOfMonth.withZone(DateTimeZone.forID("Europe/Berlin")).toString("MMM yyyy", Locale.US);
        } else {
            // just partial month.
            String Basename = firstOfMonth.withZone(DateTimeZone.forID("Europe/Berlin")).toString("MMM yyyy", Locale.US);
            String f = getPeriodStart().withZone(DateTimeZone.forID("Europe/Berlin")).dayOfMonth().getAsShortText();
            String t = getPeriodEnd().withZone(DateTimeZone.forID("Europe/Berlin")).dayOfMonth().getAsShortText();
            return Basename + " (" + f + " to " + t + ")";
        }
    }

我可能不会考虑设置默认值,因为这样你就失去了代码中的任何冗长内容,这将有助于你了解到底发生了什么。

这是一个非常简单的建议,但也许您应该只使用局部变量。

...
DateTimeZone tz = DateTimeZone.forID("Europe/Berlin");
DateTime firstOfMonth = this.getPeriodStart().withZone(tz).dayOfMonth().withMinimumValue().millisOfDay().withMinimumValue();
DateTime lastOfMonth = this.getPeriodEnd().withZone(tz).dayOfMonth().withMaximumValue().millisOfDay().withMaximumValue();
... etc ...

看看你的代码,我看到许多冗余,其中一些其他简单的局部变量可以更好地清理事情。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

切换时区进行计算 的相关文章

随机推荐

  • 减少 C++ 代码大小

    我正在研究一种用于微控制器的动态语言 编译为 C 作为一名 CS 人员 我决定首先正确地完成它 然后再担心优化 以下是我的对象系统的结构 Base Interface Number Interface Int Float Char Sequ
  • Android:方向更改会擦除对我的 ImageView 所做的修改

    我有一个应用程序 其中有 ImageView 我打开新的活动 用手指画一些东西 这个位图返回到我的 ImageView 一切都很好 但是当我现在改变方向时 我的 ImageView 活动会重新绘制或重新启动 并且 imageview 为空
  • 是否可以在 WPF ScrollViewer 上调整鼠标滚轮滚动距离?

    我发现使用鼠标滚轮时滚动太多 我有一个很短的ScrollViewer 一行高 包含几行项目WrapPanel 并且它会在一个 刻度 内向右滚动到底部 以便中间的线永远不可见 这不是一个很好的解决方案 但您可以添加一些带有文本的窗格 每行一个
  • iOS 7 上的合并冲突

    我已经更新了我的应用程序以支持 iOS 7 并且遇到了以下问题 在我的某个屏幕上 context save 我收到以下错误 NSCocoaErrorDomain Code 133020 The operation couldn t be c
  • iOS 10:NSInvalidLayoutConstraintException:约束不正确地关联不兼容类型的锚点

    更新到 iOS 10 后 我在我的一个应用程序上多次遇到此错误 NSInvalidLayoutConstraintException 约束不正确关联 不兼容类型的锚点
  • 将 System.Data.SqlClient 升级到版本 4.5.0-preview2 后,Dapper 引发 System.Data.SqlClient.SqlConnection 异常

    我最近将我的一个 ASP NET Core 应用程序从 net461 应用程序升级到 ASP NET Core 2 0 应用程序 因为过去唯一阻碍我的是 System Transactions 现在受支持 升级后 访问任何使用以下内容的函数
  • 是否有任何 Azure 数据工厂活动来获取 Cosmos 集合列表?

    Azure 数据工厂中是否有任何选项可以了解 Azure cosmos 帐户中特定数据库中可用的集合列表 想要执行特定的活动 每次执行 Azure 数据工厂管道时 该活动都会返回 cosmos db 中的集合列表 具体要求 想要从 cosm
  • 通用数据库表

    以下数据库表设计有名称吗 基本上我们有代表键 值对的通用列 编号 k1 v1 k2 v2 k3 v3 1 名称 萨姆 姓氏 史密斯 空 空 在我的应用程序中 我有许多只有一行的表 我想将它们合并到一个具有 X 列的通用表中 每行代表单个表行
  • iOS drawInRect:attributes 执行多行文本截断

    如何在尾部截断的矩形中绘制长文本字符串 我尝试将 drawInRect withAttributes 与 NSLineBreakByTruncatingTail 段落样式一起使用 但它总是在单行上呈现文本 它仅使用 NSLineBreakB
  • 使用 docker 设置 Wordpress 时的卷挂载

    快速入门 Compose 和 WordPress https docs docker com compose wordpress 提出以下建议docker compose yml version 3 3 services db image
  • 将 Tomcat Basic Auth 与新的 WebApplicationInitializer 结合使用

    好的 我以前曾在经典的 web xml 中使用过这种技术 但现在我使用 WebApplicationInitializer 时遇到了让它工作的问题 我的 WebApplicationInitializer 包含以下代码 HttpConstr
  • 跨环境管理配置文件

    您 您的公司 如何管理您构建的应用程序 系统的配置文件 让我告诉你我们是如何做到的 以及问题是什么 我在一家开发软件的公司工作 该公司约有 15 名开发人员 我们构建部署在我们的托管托管提供商处的业务线 Web 应用程序 我们的主要应用程序
  • 如何在手机中仅启用纵向和反向纵向,“sensorPortrait”在手机上不起作用?

    我不明白为什么在活动的清单中设置 sensorPortrait 属性不能让活动进入反向纵向 这就是我在清单中设置的方式
  • 嵌套/子 TransactionScope 回滚

    我试图像在 SQL Server 中嵌套事务一样嵌套 TransactionScopes net 4 0 但看起来它们的操作方式不同 我希望我的子事务在失败时能够回滚 但允许父事务决定是否提交 回滚整个操作 问题是当第一次完成时 事务会回滚
  • 使用 jQuery 设置文本选择颜色。演示无法运行

    http jsfiddle net uKdPM http jsfiddle net uKdPM 我已经设置了 selectioncss中的颜色 因此当您突出显示屏幕上的文本时 文本的颜色是粉红色的 我现在尝试在页面加载时通过 jQuery
  • 为什么我不应该总是使用shared_ptr和unique_ptr而应该使用普通指针?

    我有以下背景C and obj c所以 RC GC 是我 仍然 珍视的东西 当我开始学习时C 更深入地说 我不停地想知道为什么我会使用普通指针 当它们如此时不受管理的而不是其他替代解决方案 the 共享指针提供了一种存储引用的好方法 并且在
  • 这是核心文本吗? - Aviary 文本捏合缩放展开

    我正在考虑制作一个应用程序 用户可以更改其大小和方向UITextField 我正在研究 Aviary 应用程序 我发现用户不仅可以增加或减小文本的大小 还可以更改其方向 所以我想问的问题是 1 他们是否使用CoreText为了做到这一点 他
  • TWIG - 删除特定字符后的所有内容

    在 Twig 中 我想知道是否可以不渲染某个字符之后的所有内容 例如 如果我有字符串 Ironman 3 Marvel 并且我想删除分号之后的所有内容 这样我的字符串将变成 Ironman 3 我想知道这是否可能 你应该能够通过一些变化来做
  • iOS 7 状态栏与 iOS 6 类似

    我有一个支持横向和纵向模式的应用程序 我需要像 iOS 6 一样的行为状态栏 最简单的方法是什么 我已经尝试过 Stack Overflow 问题中的解决方案iOS 7状态栏变回iOS 6风格 https stackoverflow com
  • 切换时区进行计算

    我们的应用程序将所有日期存储为 UTC 时区 然而 我们的主要业务部门位于 欧洲 柏林 时区 2 1 具体取决于夏令时 因此 当我们确定某个时间跨度应等于哪个 月 时 我们希望使用该时区 IE 开始时给出的时间段Thursday 31 Oc