在Java中转换字符串到日历对象

我对Java不熟悉,通常使用PHP。

我正在尝试转换这个字符串:

2011年3月14日星期一16:02:37 GMT

放入一个日历对象,这样我就可以像这样轻松地拖动年和月:

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);

手动解析它是不是一个坏主意?使用子字符串方法?

任何建议都会有帮助,谢谢!

400350 次浏览

嗯,我认为复制已经存在于SimpleDateFormat类中的代码是一个坏主意。

另一方面,我个人建议如果可以的话完全避免CalendarDate,而使用Joda的时间,作为一个设计得更好的日期和时间API。例如,你需要知道SimpleDateFormat线程安全的,所以你要么需要线程局部变量,同步,要么每次使用它都需要一个新实例。Joda解析器和格式化器线程安全。

是的,如果你自己解析它,那将是一种糟糕的做法。看看SimpleDateFormat,它会将字符串转换为日期,你可以将日期设置为日历实例。

Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done

注意:根据您的环境/要求设置Locale


另请参阅

SimpleDateFormat很棒,只是要注意,当使用小时时,HHhh是不同的。HH返回基于24小时的小时数,hh返回基于12小时的小时数。

例如,下面将返回12小时的时间:

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");

虽然这将返回24小时时间:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

不需要创建新的日历,SimpleDateFormat已经在下面使用了一个日历。

SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();

(我还不能评论,这就是为什么我创建了一个新的答案)

简单的方法:

public Calendar stringToCalendar(String date, String pattern) throws ParseException {
String DEFAULT_LOCALE_NAME = "pt";
String DEFAULT_COUNTRY = "BR";
Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
Date d = format.parse(date);
Calendar c = getCalendar();
c.setTime(d);
return c;
}

博士tl;

现代方法使用java.time类。

YearMonth.from(
ZonedDateTime.parse(
"Mon Mar 14 16:02:37 GMT 2011" ,
DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
)
).toString()

2011 - 03

避免遗留的日期-时间类

现代的方法是用java。时间类。旧的日期-时间类,如Calendar,已被证明是设计糟糕,令人困惑和麻烦的。

定义一个自定义格式化程序来匹配字符串输入。

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );

解析为ZonedDateTime

ZonedDateTime zdt = ZonedDateTime.parse( input , f );

你对年和月感兴趣。java。time类包括YearMonth类用于此目的。

YearMonth ym = YearMonth.from( zdt );

如果需要,可以查询年份和月份。

int year = ym.getYear();
int month = ym.getMonthValue();

但是toString方法会生成标准ISO 8601格式的字符串。

String output = ym.toString();

把这些放在一起。

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();

转储到控制台。

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );

输入:2011年3月14日星期一16:02:37格林尼治时间

zdt: 2011 - 03 - 14 - t16:02:37z(格林尼治时间)

ym: 2011 - 03

生活的代码

看到这段代码运行在IdeOne.com

转换

如果你的必须有一个Calendar对象,你可以使用添加到旧类中的新方法将其转换为GregorianCalendar

GregorianCalendar gc = GregorianCalendar.from( zdt );

关于java.time

< em > java.time < / em >框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗产日期-时间类,如java.util.DateCalendar, &SimpleDateFormat

要了解更多信息,请参见< < em >甲骨文教程/ em >。搜索Stack Overflow可以找到很多例子和解释。规格是JSR 310

现在在维护模式中的< em > Joda-Time < / em >项目建议迁移到java.time类。

你可以直接与你的数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要java.sql.*类。Hibernate 5 &JPA 2.2支持java.time

从哪里获取java。时间类?

解析一个时区的时间,模式中的Z是时区

String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(aTime));
Log.i(TAG, "time = " + cal.getTimeInMillis());
} catch (ParseException e) {
e.printStackTrace();
}

输出:它将返回UTC时间

1508899140000

enter image description here

如果我们不像yyyy-MM-dd'T'HH:mm:ss那样设置时区。SimpleDateFormat将使用在Setting中设置的时区