GregorianCalendar:无法获得当地时间

时间:2012-03-02 21:24:33

标签: java

我正在编写一个类来简化我可以使用GregorianCalendar进行的所有操作。 我需要做的操作是: - 以字符串格式获取日期,翻译成意大利语; - 在两个日期之间进行减法。 我还没有使用过Calendar,Date和Time类,因为它们有很多不推荐使用的方法。 此外,标签不是gregoriancalendar,因为我可能需要使用另一个类(但如果不同意,可以随意修改它)。 不过这是班级:

package TruckingCompany;

import java.util.GregorianCalendar;
import java.util.Locale;

@SuppressWarnings("serial")
public class TCCalendar extends GregorianCalendar
{
public TCCalendar()
{
    super(Locale.ITALY);
}
@Override
public String toString()
{
    String str=new String();
    switch(get(DAY_OF_WEEK))
    {
        case 1: 
            str+="Domenica "; 
            break;
        case 2:
            str+="Lunedì ";
            break;
        case 3:
            str+="Martedì ";
            break;
        case 4:
            str+="Mercoledì ";
            break;
        case 5:
            str+="Giovedì ";
            break;
        case 6:
            str+="Venerdì ";
            break;
        case 7:
            str+="Sabato ";
            break;
    }
    str+=get(DAY_OF_MONTH);
    switch(get(MONTH))
    {
        case 0:
            str+=" Gennaio ";
            break;
        case 1:
            str+=" Febbraio ";
            break;
        case 2:
            str+=" Marzo ";
            break;
        case 3:
            str+=" Aprile ";
            break;
        case 4:
            str+=" Maggio ";
            break;
        case 5:
            str+=" Giungo ";
            break;
        case 6:
            str+=" Luglio ";
            break;
        case 7:
            str+=" Agosto ";
            break;
        case 8:
            str+=" Settembre ";
            break;
        case 9:
            str+=" Ottobre ";
            break;
        case 10:
            str+=" Novembre ";
            break;
        case 11:
            str+=" Dicembre ";
            break;
    }
    str+=get(YEAR)+ " Ore ";
    str+=get(HOUR_OF_DAY)+ ":";
    str+=get(MINUTE)+":";
    str+=get(SECOND);
    return str;
}
}

我使用linux并且时间正确设置为10:19(意大利小时)。 但是现在(当地时间10:20),我得到了toString方法的结果:
“Venerdì2Marzo 2012 Ore 13:21:10” 不要看意大利人的东西,问题是小时:get(HOUR_OF_DAY)返回13而不是10(22:21)。 还有,另一类更直观吗?我在javadoc中搜索过除了Calendar,GregorianCalendar,日期和时间我还没有找到任何其他内容。

6 个答案:

答案 0 :(得分:2)

如果您只想格式化日期,Java有许多语言的内置格式化程序:

final DateFormat formatter = SimpleDateFormat.getDateTimeInstance(
   DateFormat.FULL, DateFormat.FULL,
   Locale.ITALY);
System.out.println(formatter.format(new Date()));  

打印:

venerdì 2 marzo 2012 22.32.20 CET

您可以跳过Locale以使用JVM / OS默认值。如果没有我的计算机上的区域设置,则打印:

piątek, 2 marzec 2012 22:32:20 CET

答案 1 :(得分:2)

我当然会建议反对像这样扩展Calendar。我期待您能够使用SimpleDateFormat(与Locale结合使用)来完成所有这些操作而无需任何手动编码。手动指定格式或仅使用DateFormat.FULL使用特定于语言环境的完整日期/时间格式。

我的猜测是,无论出于何种原因,您的系统默认时区都没有正确显示,这可以解释一天中的小时问题。尝试打印TimeZone.getDefault().getID()以查看它正在使用的内容。

至于寻找更好的API:绝对,我衷心建议使用Joda Time代替java.util.Date / Calendar。这是一个很好的很多更好的API。 (它无论如何都不完美,但它比内置类更好。)

答案 2 :(得分:0)

答案 3 :(得分:0)

问题最有可能是

super(Locale.ITALY)

会的 根据具有给定语言环境的“默认时区”中的当前时间构造GregorianCalendar。

您很可能也需要更改TIMEZONE。

我会用这个:

  

GregorianCalendar(TimeZone区域,Locale aLocale)

Reference

答案 4 :(得分:0)

更新 Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time课程。请参阅Tutorial by Oracle

这个答案让历史原样。


a)验证计算机的时钟设置是否正确。使用类似US government time server或谷歌“当前时间”的内容。

b)使用Joda-Time

c)明确time zones以消除由于您自己的Java环境的默认值引起的混淆。使用时区名称,而不是既不标准也不唯一的3字母代码。

您可以为渲染字符串创建特定格式。但首先要考虑使用特定于您的语言环境的内置格式。

以下是一些Joda-Time代码示例。

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Time Zone list… http://joda-time.sourceforge.net/timezones.html  (not quite up-to-date, read page for details)
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Rome" );

DateTime nowInItaly = new DateTime( timeZone );

DateTimeFormatter formatter = DateTimeFormat.fullDateTime().withLocale( Locale.ITALY );
String dateTimeString = formatter.print( nowInItaly );

转储到控制台...

System.out.println( "nowInItaly: " + nowInItaly );
System.out.println( "dateTimeString: " + dateTimeString );

跑步时......

nowInItaly: 2013-12-28T04:41:19.776+01:00
dateTimeString: sabato 28 dicembre 2013 4.41.19 CET

答案 5 :(得分:0)

TL;博士

ZonedDateTime.now().plusDays( 10 ).format(
    DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.ITALY )
)
  

giovedì15febbraio 2018 12:35:34 Ora standard del Pacifico USA

java.time

  

我需要做的操作是: - 以字符串格式获取日期,翻译成意大利语; - 在两个日期之间进行减法。

获取您所在时区的当前时刻。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Capture current moment as seen on wall-clock of people in a particular region.

生成一个String来表示该值,并对特定语言和文化进行本地化。生成表示日期时间值的String时,DateTimeFormatter类可以自动进行本地化。

要进行本地化,请指定:

  • FormatStyle确定字符串的长度或缩写。
  • Locale确定(a)翻译日期名称,月份名称等的人类语言,以及(b)决定缩写,大写,标点符号,分隔符等问题的文化规范

示例:

Locale l = Locale.ITALY ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );
  

lunedì5febbraio 2018 21:28:00 Ora标准dell'Europa centrale

了解时区和区域设置是正交的,完全分开。一个定义了日期时间的含义,另一个定义了表示。

日期时间数学

使用Period表示未连接到时间线的时间跨度 - 数月 - 天,或Duration表示小时 - 分钟 - 秒。

Period p = Period.ofDays( 10 ) ;  // Ten days.

通过调用minusplus方法进行数学计算。

ZonedDateTime zdtLater = zdt.plus( p ) ; // Adding ten days later.

您可以计算经过的时间。

Period delta = Period.between( zdt , zdtLater ) ;

致电Period::toString以在standard ISO 8601 format生成字符串。

  

P10D

旧版代码

如果必须与尚未转换为java.time的旧代码进行交互操作,则可以使用添加到旧类中的新方法进行转换。

相当于GregorianCalendarZonedDateTime

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;  // Convert from legacy class to modern class.

关于 java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore