【问题标题】:How to format the week number to a desired format in H2如何在 H2 中将周数格式化为所需的格式
【发布时间】:2017-01-09 06:54:27
【问题描述】:

我想要一个带有周数和年份的日期格式,ISO 格式为 yyyy-'W'ww。但是,由于 H2 数据库中只有周功能,我只能获得没有年份的周数。如何以添加默认年份的方式进行格式化。像 2016 年-'W'ww。

目前我正在使用这个功能(这绝对不是正确的方法)

WEEK(PARSEDATETIME(TRUNC(" + this.fieldName + "),'2016ww') WEEK(PARSEDATETIME(TRUNC(" + this.fieldName + "),'2016-ww')

我无法获得其他可以做的事情。任何人都可以在这里帮助我

【问题讨论】:

  • this.fieldName的数据类型和内容到底是什么?
  • 是列名。假设“时间”的数据类型为“日期”
  • 澄清应该作为对您的问题的编辑而不是作为 cmets 发布。

标签: java date timestamp h2 week-number


【解决方案1】:

在不同的库中有几种有效的解决方案。但是,您需要知道使用标准日历年“y”是错误的。相反,您必须使用带有符号“Y”(大写字母)的星期日期(或称为基于周的年份)。

使用旧 Calendar-stuff 的示例

java.sql.Date sqlDate = new java.sql.Date(2017 - 1900, 0, 1); // 2017-01-01
GregorianCalendar gcal = new GregorianCalendar();
gcal.setFirstDayOfWeek(Calendar.MONDAY);
gcal.setMinimalDaysInFirstWeek(4);
gcal.setTime(sqlDate);
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-'W'ww");
System.out.println(sdf.format(gcal.getTime())); // 2016-W52

使用 Java-8 的示例:

java.sql.Date sqlDate = new java.sql.Date(2017 - 1900, 0, 1); // 2017-01-01

LocalDate ld = sqlDate.toLocalDate();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-'W'ww", Locale.FRANCE);
System.out.println(dtf.format(ld)); // 2016-W52

附注:我在这里选择了法国的语言环境,以确保 ISO-8601 所需的正确周配置。


使用我的库 Time4J 的示例,如果您还计划对获得的日历周进行一些算术运算(例如 plusWeeks(5) 或计划获得一些风格的本地化输出):

java.sql.Date sqlDate = new java.sql.Date(2017 - 1900, 0, 1); // 2017-01-01
PlainDate value = JDBCAdapter.SQL_DATE.translate(sqlDate);
CalendarWeek cw =
    CalendarWeek.of(
        value.get(PlainDate.YEAR_OF_WEEKDATE),
        value.get(Weekmodel.ISO.weekOfYear())
    );
System.out.println(cw.toString()); // 2016-W52

【讨论】:

    【解决方案2】:

    tl;博士

    org.threeten.extra.YearWeek                       // Handy class found in the ThreeTen-Extra library added to your project.
    .from(                                            // Determine the week number and the week-based year number from the passed `LocalDate` object, according to standard ISO 8601 definition of a week.
        myResultSet.getObject( … , LocalDate.class )  // Produces a `LocalDate` object to pass to `YearWeek.from`.  
    )                                        
    .toString()                                       // Generate a String in standard ISO 8601 format: yyyy-Www
    

    2018-W13

    详情

    当您从 H2 获取 Date 类型为 java.sql.Date 时,转换为 java.time.LocalDate

    LocalDate ld = mySqlDate.toLocalDate();
    

    您可以查询 ISO 8601 标准 definition of a week 其中第 1 周包含一年中的第一个星期四,并且从星期一到星期日运行。

    int weekNumber = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
    

    提取年份。

    int year = ld.getYear();
    

    组装您的标准 ISO 8601 字符串。

    String output = year + "-W" + String.format( "%02d ", weekNumber );
    

    更简单的是使用来自ThreeTen-Extra 项目的YearWeek 类。

    String output = YearWeek.from( ld ).toString() ;
    

    JDBC 4.2

    从 JDBC 4.2 及更高版本开始,您可以直接与数据库交换 java.time 对象。无需再次过度使用 java.util 或 java.sql 日期时间类。

    LocalDate ld = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;  // Capture the current date as seen in the wall-clock used by the people in a certain region (a time zone).
    myPreparedStatement.setObject( … , ld ) ;
    

    和检索。

    LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
    

    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      猜你喜欢
      • 2020-07-07
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      • 2019-07-01
      • 1970-01-01
      • 2019-12-09
      相关资源
      最近更新 更多