SimpleDateFormat 返回带有前导零的日期,例如 0022 Feb 2018
SimpleDateFormat is returning date with leading zeros like 0022 Feb 2018
这是我的 SimpleDateFormat
实例:
public static final SimpleDateFormat DD_MMM_YYYY =
new SimpleDateFormat("dd MMM yyyy");
我正在将以毫秒为单位的时间戳转换为这种日期格式。
有时 returns 正确的日期如下:
22 Feb 2018
但有时(在极少数情况下)returns 日期不正确,例如:
0022 Feb 2018
为什么要添加两个前导零?
我的方法如下-
public static String convertLongToDate(long timestamp) {
Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
long todaysTimestamp = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_YEAR, -1);
long yesterdayTimestamp = calendar.getTimeInMillis();
calendar.setTimeInMillis(timestamp);
String timeString;
String todaysDateStr = DD_MMM_YYYY.format(todaysTimestamp);
String givenDateStr = DD_MMM_YYYY.format(calendar.getTimeInMillis());
Log.d("Check", "date-> todaysDateStr=" + todaysDateStr + ", givenDateStr=" + givenDateStr+", todayLength="+todaysDateStr.length()+", givenLength="+givenDateStr.length());
if (todaysDateStr.equalsIgnoreCase(givenDateStr)) {
timeString = AppConstants.TODAY;
} else if (DD_MMM_YYYY.format(yesterdayTimestamp).equalsIgnoreCase(givenDateStr)) {
timeString = AppConstants.YESTERDAY;
} else {
timeString = givenDateStr;
}
timeString = timeString.trim();
return timeString;
}
没有关于您如何使用格式化程序的更多信息,很难判断问题出在哪里。
但我猜这是因为 SimpleDateFormat
不是 thread-safe。
当 运行 它处于 multi-thread 环境中时,奇怪的事情开始发生。只需查看 google,您就会发现很多相关文章:https://www.google.com/search?q=simpledateformat+not+thread+safe
更新:
使用你的代码,我无法重现问题,但我仍然认为它与在多线程环境中使用 non-threadsafe class 有关 - 这是我所知道的唯一问题这可能会发生,特别是 "sometimes" 因素。
愚蠢的问题: 是否有任何 AppConstants
值有前导零?随便问问,谁知道...
备选方案
您可以为此使用更好的 API,例如 ThreeTen Backport:
有了它,您的代码变得更加清晰易懂 understand/maintain:
public static String convertLongToDate(long timestamp) {
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd MMM yyyy");
ZonedDateTime today = ZonedDateTime.now(ZoneId.systemDefault());
ZonedDateTime yesterday = today.minusDays(1);
ZonedDateTime givenDate = Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault());
String timeString;
// compare just the date (day, month, year)
// no need to convert to string to compare if dates are the same
if (today.toLocalDate().equals(givenDate.toLocalDate())) {
timeString = AppConstants.TODAY;
} else if (yesterday.toLocalDate().equals(givenDate.toLocalDate())) {
timeString = AppConstants.YESTERDAY;
} else {
timeString = givenDate.format(f);
}
timeString = timeString.trim();
return timeString;
}
这个 API 是线程安全的,SimpleDateFormat
有时会发生的奇怪事情在这里不会发生。
或者,如果你不想使用另一个API,你可以使用这个post的解决方案:http://fahdshariff.blogspot.com.br/2010/08/dateformat-with-multiple-threads.html
如果您显示当前日期和特定格式,则使用下面的代码。
Date c = Calendar.getInstance().getTime(); // get current date and time.
System.out.println("Current time => " + c);
SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy"); // define your format.
String formattedDate = df.format(c);
System.out.println("New Date To Show::"+formattedDate);
这是我的 SimpleDateFormat
实例:
public static final SimpleDateFormat DD_MMM_YYYY =
new SimpleDateFormat("dd MMM yyyy");
我正在将以毫秒为单位的时间戳转换为这种日期格式。
有时 returns 正确的日期如下:
22 Feb 2018
但有时(在极少数情况下)returns 日期不正确,例如:
0022 Feb 2018
为什么要添加两个前导零?
我的方法如下-
public static String convertLongToDate(long timestamp) {
Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
long todaysTimestamp = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_YEAR, -1);
long yesterdayTimestamp = calendar.getTimeInMillis();
calendar.setTimeInMillis(timestamp);
String timeString;
String todaysDateStr = DD_MMM_YYYY.format(todaysTimestamp);
String givenDateStr = DD_MMM_YYYY.format(calendar.getTimeInMillis());
Log.d("Check", "date-> todaysDateStr=" + todaysDateStr + ", givenDateStr=" + givenDateStr+", todayLength="+todaysDateStr.length()+", givenLength="+givenDateStr.length());
if (todaysDateStr.equalsIgnoreCase(givenDateStr)) {
timeString = AppConstants.TODAY;
} else if (DD_MMM_YYYY.format(yesterdayTimestamp).equalsIgnoreCase(givenDateStr)) {
timeString = AppConstants.YESTERDAY;
} else {
timeString = givenDateStr;
}
timeString = timeString.trim();
return timeString;
}
没有关于您如何使用格式化程序的更多信息,很难判断问题出在哪里。
但我猜这是因为 SimpleDateFormat
不是 thread-safe。
当 运行 它处于 multi-thread 环境中时,奇怪的事情开始发生。只需查看 google,您就会发现很多相关文章:https://www.google.com/search?q=simpledateformat+not+thread+safe
更新:
使用你的代码,我无法重现问题,但我仍然认为它与在多线程环境中使用 non-threadsafe class 有关 - 这是我所知道的唯一问题这可能会发生,特别是 "sometimes" 因素。
愚蠢的问题: 是否有任何 AppConstants
值有前导零?随便问问,谁知道...
备选方案
您可以为此使用更好的 API,例如 ThreeTen Backport:
有了它,您的代码变得更加清晰易懂 understand/maintain:
public static String convertLongToDate(long timestamp) {
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd MMM yyyy");
ZonedDateTime today = ZonedDateTime.now(ZoneId.systemDefault());
ZonedDateTime yesterday = today.minusDays(1);
ZonedDateTime givenDate = Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault());
String timeString;
// compare just the date (day, month, year)
// no need to convert to string to compare if dates are the same
if (today.toLocalDate().equals(givenDate.toLocalDate())) {
timeString = AppConstants.TODAY;
} else if (yesterday.toLocalDate().equals(givenDate.toLocalDate())) {
timeString = AppConstants.YESTERDAY;
} else {
timeString = givenDate.format(f);
}
timeString = timeString.trim();
return timeString;
}
这个 API 是线程安全的,SimpleDateFormat
有时会发生的奇怪事情在这里不会发生。
或者,如果你不想使用另一个API,你可以使用这个post的解决方案:http://fahdshariff.blogspot.com.br/2010/08/dateformat-with-multiple-threads.html
如果您显示当前日期和特定格式,则使用下面的代码。
Date c = Calendar.getInstance().getTime(); // get current date and time.
System.out.println("Current time => " + c);
SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy"); // define your format.
String formattedDate = df.format(c);
System.out.println("New Date To Show::"+formattedDate);