项目中有个需求是时间戳转字符串,需要显示星期,且需要展示为周一、周二等。
SimpleDateFormat中有formatWeekday方法,内容如下:
private String formatWeekday(int count, int value, boolean useDateFormatSymbols,
boolean standalone) {
if (useDateFormatSymbols) {
final String[] weekdays;
if (count == 4) {
weekdays = standalone ? formatData.getStandAloneWeekdays() : formatData.getWeekdays();
} else if (count == 5) {
weekdays =
standalone ? formatData.getTinyStandAloneWeekdays() : formatData.getTinyWeekdays();
} else { // count < 4, use abbreviated form if exists
weekdays = standalone ? formatData.getShortStandAloneWeekdays() : formatData.getShortWeekdays();
}
return weekdays[value];
}
return null;
}
当时间类型中的周为EEEE时,weekdays的值会通过formatData.getWeekdays()获取,formatData为DateFormatSymbols实例,且DateFormatSymbols提供了设置weekdays方法,如下:
/**
* Sets weekday strings. For example: "Sunday", "Monday", etc.
* @param newWeekdays the new weekday strings. The array should
* be indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
*/
public void setWeekdays(String[] newWeekdays) {
weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length);
cachedHashCode = 0;
}
然后我就提供了如下转换方法:
public static final String LONG_DATE_FORMAT_WEEK = "yyyy-MM-dd EEEE";
public static final String[] DAY_OF_WEEK_NAMES = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
public static String timeMillis2String(long timeMillis) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(timeMillis);
Date date = c.getTime();
SimpleDateFormat sdf = new SimpleDateFormat(LONG_DATE_FORMAT_WEEK, Locale.getDefault());
DateFormatSymbols dateFormatSymbols = sdf.getDateFormatSymbols();
dateFormatSymbols.setWeekdays(DAY_OF_WEEK_NAMES);
sdf.setDateFormatSymbols(dateFormatSymbols);
return sdf.format(date);
}
但是当待解析的时间戳转换结果为周六时,会导致数据越界:
原因是忽略了setWeekdays以及weekdays中的注释
/**
* Weekday strings. For example: "Sunday", "Monday", etc. An array
* of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>weekdays[0]</code> is ignored.
* @serial
*/
String weekdays[] = null;
即,这个数组中的下标要与Calendar#SUNDAY等相同,且该数组长度需要八位,第0位是会被忽略的。解决办法就是将自定义的日期数组改为:
public static final String[] DAY_OF_WEEK_NAMES = {"", "周日", "周一", "周二", "周三", "周四", "周五", "周六"};