我正在开发一款经常从时区到TZ的Android应用。我随着时间和TZ得到各种错误。最新的错误是,当我加载平面文件时(见下文),一切看起来都不错。当我保存应用程序环境(也就是所有变量/对象到sharedprefs)时,停止然后重新启动应用程序,显示的时间不再是本地而是UTC。
我开始使用默认/本地TZ开发应用程序。然而,这与DST和各种TZ变得非常复杂。因此,我目前的方法是以UTC格式在应用程序中存储时间,并根据需要计算UTC时间之间的差异。然后根据需要将UTC存储时间转换为本地TZ以进行用户交互。
我认识到有许多与android时间相关的帖子。我想我已经阅读过java.util.date和Joda上的大部分内容。但是,我仍然被卡住了。所以,这里......
我有3个应用时间来源。 1)我从平面文件中读取UTC字符串2)我从系统时间戳(UTC)的Epoch开始得到毫秒。 3)我通过rest API在字符串中获得UTC。该应用程序在3个类别之间进行了大量计算,例如时差,添加时间等。下面我将为每个类别发布我的代码
1 - 转换来自文件的字符串UTC
public static Date string2date(String strformat, String strdate){
Date tdate = timestamp();
TimeZone tz = TimeZone.getDefault() ;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SimpleDateFormat formatter = new SimpleDateFormat(strformat);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateInString = strdate;
try {
tdate = formatter.parse(dateInString);
} catch (ParseException e) {
e.printStackTrace();
}
return tdate;
}
2 - 自Epoch
以来获得毫秒数public static Date timestamp() {
Calendar localCalendar = Calendar.getInstance(TimeZone.getDefault());
//Date currentTime = localCalendar.getTime();
Date currentTime = GetUTCdatetimeAsDate();
return currentTime;
public static Date GetUTCdatetimeAsDate()
{
//note: doesn't check for null
return StringDateToDate(GetUTCdatetimeAsString());
}
public static String GetUTCdatetimeAsString()
{
final SimpleDateFormat sdf = new SimpleDateFormat(longdt);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = sdf.format(new Date());
return utcTime;
}
public static Date StringDateToDate(String StrDate)
{
Date dateToReturn = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(longdt);
try
{
dateToReturn = (Date)dateFormat.parse(StrDate);
}
catch (ParseException e)
{
e.printStackTrace();
}
return dateToReturn;
}
3 - 通过其他API在字符串中获取UTC(格式为" 2017-02-10T01:09:00Z")
try {
Calendar tempCal = ISO8601.toCalendar(dateLocal);
Log.e (" fbu "," fsutc " + tempCal.getTime() );
ISODepDate = tempCal.getTime();
tempCal = ISO8601.toCalendar(dateLocal2);
ISOArrDate = tempCal.getTime();
//ab.setTimeZone(PST);
Log.e (" fbu "," fsutc " + dateLocal + " / " + dateLocal2);
Log.e (" fbu "," fsutc " + ISODepDate + " / " + ISOArrDate);
}
catch (Exception a){
int aa = 1;
Log.e (" exception "," a " + a);
}
public static Calendar toCalendar(final String iso8601string)
throws ParseException {
Calendar calendar = GregorianCalendar.getInstance();
TimeZone tz = TimeZone.getDefault() ;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
String s = iso8601string.replace(".000Z", "+00:00");
try {
s = s.substring(0, 22) + s.substring(23); // to get rid of the ":"
} catch (IndexOutOfBoundsException e) {
throw new ParseException("Invalid length", 0);
}
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
calendar.setTime(date);
return calendar;
}
4 - 最后,这是我正在使用的"显示"以上3个时间类别在当地时间。
public String UTCtoLocal(Date indate, Boolean formatLong) {
Date utcDate = indate;
String result;
//Log.e( " utc "," indate " + indate);
/*utcDate = your own initialization here;*/
Date localDate = new Date(utcDate.getTime() + TimeZone.getDefault().getRawOffset());
//Log.e( " utc "," localdate " + localDate);
if (formatLong){
result = longd.format(localDate);
} else {
result = shortt.format(localDate);
}
return result;
问题是,假设我以UTC格式存储并在本地显示,a)我是否正确实施了1-4项? b)上面的代码是否实际以UTC格式存储时间并显示在本地?
平面文件加载后一切看起来都不错。重启后,时间以UTC与本地显示。