Java Postgresql 星期几的常量

Java constants for Postgresql's days-of-week

Postgresql returns 星期几使用 EXTRACTdow 以下方式:0 是星期日,1 是星期一,一直到 6 是星期六, see official documentation

我正在 Java 中或 JDBC 中寻找一些官方常量,或者可能是一些与此编号匹配的标准库(Apache Commons?)。

您可以使用 Calendar 常量减 1,这样您就可以匹配 PostgreSQL 值,即:Calendar.SUNDAY = 1

根据同样的 official documentation 你应该使用 isodow:

星期一 (1) 到星期日 (7) 是星期几

tl;博士

I am looking for some official constants either in Java proper

是的,Java 使用与 Postgres 中的 isodow 函数相同的标准 ISO 8601 定义在 DayOfWeek 枚举中定义七个星期值从周一到周日,第 1-7 天。

DayOfWeek.WEDNESDAY.getValue()  // Returns an `int` 1-7 for Monday-Sunday. 

3

java.time.DayOfWeek枚举

作为 suggests, use the Postgres function isodow

isodow 中的“iso”指的是 ISO 8601 standard and its definition of week,其中 1-7 表示周一至周日。

Java 在其 DayOfWeek 枚举中支持相同的周定义。 class 为您定义了七个对象,一个对应一周中的每一天,例如 DayOfWeek.MONDAY。要获取每个对象的星期几,周一至周日为 1-7,请调用 DayOfWeek::getValue。但是在您的 Java 编码中,请专注于使用和传递 DayOfWeek 对象本身,而不仅仅是整数。

int dowNumber = DayOfWeek.WEDNESDAY.getValue() ;

3

从整数到 DayOfWeek 对象有点棘手,因为我们需要使用索引访问 Java 数组。该索引表示从零开始计数,因此从您的星期几中减去一个。星期三是第 3 天,因此将结果 2 减去 1 以访问 DayOfWeek.WEDNESDAY

DayOfWeek dow = DayOfWeek.values()[ 3-1 ] ;  // Get object named `WEDNESDAY` using zero-based index counting, so 3 - 1 = 2.

dow.toString(): WEDNESDAY

顺便说一下,要自动本地化星期几的名称,请调用 DayOfWeek::getDisplayName

Java 而不是 SQL

I am currently writing a query that is finding customers that currently have a Friday 10:00 AM in their respective time zone, so I need to pass in the concept of "Friday" into the query and of course I don't want to hard-code it.

在 Java 中使用行业领先的 java.time classes 进行这项工作可能比在 [=202] 中更好=].

你必须非常注意时区。明确时区而不是依赖隐式默认时区。

时区对于确定日期至关重要。对于任何给定时刻,日期在全球范围内因地区而异。例如,Paris France is a new day while still “yesterday” in Montréal Québec.

午夜后几分钟

如果未指定时区,JVM 将隐式应用其当前默认时区。该默认设置可能随时更改,因此您的结果可能会有所不同。最好明确指定您的 desired/expected 时区作为参数。

指定 proper time zone name in the format of continent/region, such as America/Montreal, Africa/CasablancaPacific/Auckland。切勿使用 ESTIST 等 3-4 字母缩写,因为它们 不是 真正的时区,未标准化,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

如果你想使用 JVM 当前的默认时区,请求它并作为参数传递。如果省略,则隐式应用 JVM 的当前默认值。最好是明确的,因为默认值可能会在任何时候 在运行时 中被 JVM 中任何应用程序的任何线程中的任何代码更改。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

接下来,获取下一个星期五,如果已经是星期五,则坚持今天。使用 TemporalAdjuster to adjust between dates, specifically the one found in TemporalAdjusters.

LocalDate nextOrSameFriday = today.with( TemporalAdjusters.nextOrSame( DayOfWeek.FRIDAY ) ) ;

你说你的目标是上午 10 点。

LocalTime lt = LocalTime.of( 10 , 0 ) ;  // 10 AM.

结合日期和时区获得特定时刻。

ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

通过提取 Instant 对象调整为 UTC。同一时刻,时间轴上的同一点,但挂钟时间不同。

Instant instant = zdt.toInstant() ;

制定您的 SQL 以查询类型为 TIMESTAMP WITH TIME ZONE 的数据库列。

String sql = "SELECT * from tbl WHERE when_col = ? ; " ;
…
myPreparedStatement.setObject( … , instant ) ;

并检索。

Instant instant = myResultSet.getObject( … , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

在这种方法中,您需要 Postgres 中的 dowisodow 函数。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

您可以直接与您的数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes.

从哪里获得java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.