Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 解析和格式化日期_Java_Android_Datetime_Datetime Format_Datetime Parsing - Fatal编程技术网

Java 解析和格式化日期

Java 解析和格式化日期,java,android,datetime,datetime-format,datetime-parsing,Java,Android,Datetime,Datetime Format,Datetime Parsing,我有以下代码用于以字符串形式获取日期yyyy-MM-dd-HH:MM:ss(UTC时区),并将其转换为eed(st,nd,rd,th)MMMM-yyy-HH:MM(设备的默认时区) 然而,我的问题是,我这样做的方式是代码看起来凌乱和低效。有没有一种方法可以实现我想要的,而无需对同一日期进行多次格式化和解析以提高效率?还有其他的改进吗 最好支持Android API级别14 String inputExample=“2017-06-28 22:44:55”; //将UTC转换为设备默认值(本地)

我有以下代码用于以字符串形式获取日期
yyyy-MM-dd-HH:MM:ss
(UTC时区),并将其转换为
eed(st,nd,rd,th)MMMM-yyy-HH:MM
(设备的默认时区)

然而,我的问题是,我这样做的方式是代码看起来凌乱和低效。有没有一种方法可以实现我想要的,而无需对同一日期进行多次格式化和解析以提高效率?还有其他的改进吗

最好支持Android API级别14


String inputExample=“2017-06-28 22:44:55”;
//将UTC转换为设备默认值(本地)
专用字符串转换UTC(字符串日期字符串){
试一试{
SimpleDataFormat df=新的SimpleDataFormat(“yyyy-MM-dd HH:MM:ss”);
df.setTimeZone(TimeZone.getTimeZone(“UTC”));
Date temp=df.parse(dateStr);
setTimeZone(TimeZone.getDefault());
字符串local=df.format(temp);
datelocaldate=df.parse(dateStr);
SimpleDataFormat outputDF1=新的SimpleDataFormat(“EEEE”);
SimpleDataFormat outputDF2=新SimpleDataFormat(“MMMM yyy HH:mm”);
返回outputDF1.format(temp)+前缀(local)+outputDF2.format(temp);
}catch(java.text.ParseException-pE){
Log.e(“,”解析异常“,pE);
返回null;
}
}
私有字符串前缀(字符串dateStr){
试一试{
SimpleDataFormat outputDF=新SimpleDataFormat(“yyyy-MM-dd HH:MM:ss”);
Date temp=outputDF.parse(dateStr);
SimpleDataFormat df=新的SimpleDataFormat(“d”);
intd=Integer.parseInt(df.format(temp));

如果(1使用
SimpleDateFormat
,则可能没有多少改进。因为您的输出格式有
EEEE
(一周中的一天)和
MMMM
(月份名称),您必须解析日期才能知道这些值。如果不使用日期格式化程序,您必须执行大量的
if
,才能获得每个值的相应名称


在Android中,作为
SimpleDataFormat
的替代方案,您可以使用,这是Java8新的日期/时间类的一个很好的后台端口,以及(有关如何使用它的更多信息)

所有类都在
org.threeten.bp
包下面。在下面的代码中,我也使用
Locale.ENGLISH
,否则它将使用系统的默认值(因为我的不是英语,我假设你的是):

String inputExample=“2017-06-28 22:44:55”;
//输入解析器
DateTimeFormatter parser=DateTimeFormatter.of模式(“yyyy-MM-dd HH:MM:ss”,Locale.ENGLISH);
//解析日期并设置为UTC
ZoneDateTime z=LocalDateTime.parse(inputExample,parser).atZone(ZoneOffset.UTC);
//自定义值映射-将每个数值映射到带有后缀(st、nd…)的字符串
Map textLookup=新建HashMap();

对于(int i=1;我投票将这个问题作为离题题结束,因为它属于“开”。@shmosel感谢您指出这一点。我将在这里发布。您必须分析代码以找出导致性能低下的原因。至于“混乱”部分-好吧,java.util.date API被广泛认为是“混乱”的,您可以做的不多。重构代码以找到更干净的方法。在开始重构之前,请确保您有一套防弹的单元测试。如果确定此问题已解决,请继续
String inputExample = "2017-06-28 22:44:55";

//Converts UTC to Device Default (Local)
private String convertUTC(String dateStr) {
    try {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        df.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date temp = df.parse(dateStr);
        df.setTimeZone(TimeZone.getDefault());
        String local = df.format(temp);
        Date localDate = df.parse(dateStr);
        SimpleDateFormat outputDF1 = new SimpleDateFormat("EEEE ");
        SimpleDateFormat outputDF2 = new SimpleDateFormat(" MMMM yyyy HH:mm");
        return outputDF1.format(temp) + prefix(local) + outputDF2.format(temp);
    } catch(java.text.ParseException pE) {
        Log.e("", "Parse Exception", pE);
        return null;
    }
}

private String prefix(String dateStr) {
    try {
        SimpleDateFormat outputDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date temp = outputDF.parse(dateStr);
        SimpleDateFormat df = new SimpleDateFormat("d");
        int d = Integer.parseInt(df.format(temp));
        if(1 <= d && d <= 31) {
            if(11 <= d && d <= 13)
                return d + "th";
            switch (d % 10) {
                case 1: return d + "st";
                case 2: return d + "nd";
                case 3: return d + "rd";
                default: return d + "th";
            }
        }
        Log.e("", "Null Date");
        return null;
    } catch(java.text.ParseException pE) {
        Log.e("", "Parse Exception", pE);
        return null;
    }
}
String inputExample = "2017-06-28 22:44:55";
// parser for input
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
// parse the date and set to UTC
ZonedDateTime z = LocalDateTime.parse(inputExample, parser).atZone(ZoneOffset.UTC);

// map of custom values - map each numeric value to its string with suffix (st, nd...)
Map<Long, String> textLookup = new HashMap<Long, String>();
for (int i = 1; i <= 31; i++) {
    String suffix = "";
    switch (i) {
    case 1:
    case 21:
    case 31:
        suffix = "st";
        break;
    case 2:
    case 22:
        suffix = "nd";
        break;
    case 3:
    case 23:
        suffix = "rd";
        break;
    default:
        suffix = "th";
    }
    textLookup.put((long) i, i + suffix);
}
// output formatter
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // day of week
    .appendPattern("EEEE ")
    // append day with suffix (use map of custom values)
    .appendText(ChronoField.DAY_OF_MONTH, textLookup)
    // rest of pattern
    .appendPattern(" MMMM yyyy HH:mm")
    // create formatter with English locale
    .toFormatter(Locale.ENGLISH);

// print date, convert it to device default timezone
System.out.println(fmt.format(z.withZoneSameInstant(ZoneId.systemDefault())));