【问题标题】:How to change the date format of List<Date>如何更改 List<Date> 的日期格式
【发布时间】:2019-06-03 16:43:11
【问题描述】:

我有一个列表,当我打印/显示它的内容时,我会得到特定格式的日期。假设我想以不同的格式获取它们,我如何选择我希望打印列表的格式?

public List<Date> TimeHistory = new ArrayList<Date>();
ArrayAdapter<Date> adapter = new ArrayAdapter<Date>(getActivity(), R.layout.listview_timehistory, R.id.tvTime,TimeHistory);

例如,这段代码给了我想要的列表,但我想以不同的格式获取它。

顺便说一句 当我将项目添加到列表中时,我使用 simpleDateFormat 和我想要的格式。但是当列表视图中显示的项目时,它们似乎没有使用这种格式。

if(Info.get("TIME")!=null)
                    {
                        SimpleDateFormat  format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
                        try {
                            Date date = format.parse(Info.get("TIME"));
                            message.TimeHistory.add(date);
                        }
                        catch (Exception e){

                        }
                    }

【问题讨论】:

  • 如何打印日期?使用 SimpleDateFormat 类??
  • 那么您可能需要改用ArrayAdapter&lt;String&gt;。你能使用 Java 8 的特性吗?
  • 好吧,我并没有真正打印它们,我在列表视图中看到它们。是的,我可以使用 Java 8 功能。
  • 我建议你不要使用SimpleDateFormatDate。这些类设计不良且过时,尤其是前者,尤其是出了名的麻烦。而是使用来自java.time, the modern Java date and time APILocalDateTimeDateTimeFormatter
  • 如果您的问题特定于 Android 中的 ArrayAdapter 类,您应该明确说明并使用 Android 标记您的问题。

标签: java date arraylist format android-arrayadapter


【解决方案1】:

tl;博士

format.parse( Info.get("TIME") )    // Get a legacy `java.util.Date` object.
.toInstant()                        // Convert from legacy class to modern class.
.atOffset(                          // Convert from the basic `Instant` class to the more flexible `OffsetDateTime` class.
    ZoneOffset.UTC                  // Specify the offset-from-UTC in which you want to view the date and time-of-day. 
)  
.format(                            // Generate text representing the value of our `OffsetDateTime` object.
    DateTimeFormatter.ofPattern( "dd/MM/yyyy HH:mm:ss" )  // Specify your custom formatting pattern. Better to cache this object, in real work. 
)                                   // Returns a `String

Date 几年前被Instant 取代。 Instant::toString 方法使用了一种更好的格式,一种现代标准格式。

Instant.now().toString() 

2019-06-04T20:11:18.607231Z

转换您的Date 对象,myDate.toInstant()

详情

Object::toString 方法并不灵活。其目的是在调试或记录时提供对象的简单视图。

但是,正如您所见,java.util.Date::toString 的实现很糟糕。

首先,将 JVM 的当前默认时区应用于存储在 Date 对象中的时刻。那一刻实际上是在UTC。这种误报会造成时区实际上不在对象中的错觉。

其次,Date::toString 方法使用了糟糕的格式,只有英文,人类难以阅读,机器也难以解析。

Date 类还有许多其他问题。你根本不应该再使用这个类。随着 JSR 310 的采用,它被 java.time.Instant 类所取代。

您应该尽可能将Date 替换为Instant。在你不能的地方,转换。调用添加到旧类的新方法。

Instant instant = myJavaUtilDate.toInstant() ;

幸运的是,Instant 上的 toString 方法设计得更好。它告诉你真相,在UTC 的片刻。它使用标准的ISO 8601 格式。该标准是专门为将日期时间值作为文本而发明的,其方式既易于机器解析,又易于跨文化的人类阅读。

String output = instant.toString() ;

2019-06-04T20:11:18.607231Z

所以Instant 对象的列表将如下所示。

Instant now = Instant.now();
List < Instant > instants = List.of( now.minus( 1L , ChronoUnit.HOURS ) , now , now.plus( 20L , ChronoUnit.MINUTES ) );
String output = instants.toString();

[2019-06-04T19:41:51.210465Z, 2019-06-04T20:41:51.210465Z, 2019-06-04T21:01:51.210465Z]

你的代码 sn-p

至于您的代码 sn-p,转换为 java.time.OffsetDateTime 对象,并使用自定义格式模式生成文本。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/yyyy HH:mm:ss" ) ;
 …   
if(Info.get("TIME")!=null)
{
    try {
        Date date = format.parse( Info.get("TIME") ) ;
        Instant instant = date.toInstant() ;
        OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
        String output = odt.format( f ) ;
        message.TimeHistory.add(date);
    }
    catch (Exception e){

    }
}

【讨论】:

  • 很好的答案,但我的列表类型是日期,这也是我对其进行排序的方式,并且您解释了如何转换每个项目。正如我发布的那样,适配器将它们一起打印。那么如何在 ArrayAdapter 中转换整个列表打印?
  • @Ohados 我强烈建议不要再使用java.util.Date。更改为ArrayAdapter&lt;Instant&gt;。现有的Date 对象可以通过调用Date::toInstant 进行转换,尽管我会完全从您的代码库中删除Date。遗留的日期时间类真的很糟糕。 JSR 310 被 Sun、Oracle 和 JCP 社区采用是有原因的。
【解决方案2】:

如果您执行System.out.println(TimeHistory) 之类的操作,或者如果您在调试时“仅”查看日期,则会调用java.util.Dates toString() 方法。 System.out.println(TimeHistory) 调用java.util.AbstractCollections toString() 方法,对每个项目执行调用toString() 方法。

如果你想改变这种行为,你应该扩展java.util.Date并覆盖toString()-方法

【讨论】:

  • 对于不想使用 Instant 但仍想使用 Date 的人,这就是答案!
【解决方案3】:

最好使用 simpleDateFormat 类,您可以在其中使用字符串指定格式: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

但是 Date 对象是旧的,你可以使用 Java8 日期类来表示时间

编辑后: 显然,现在您想要更改 ArrayAdapter 的行为很明显,因为默认情况下它使用 OBJECT.toString() 方法来显示数据,因此它使用 java.util.Date.toString()。你想改变这种行为,这就是你想要的:

Displaying custom objects in ArrayAdapter - the easy way?

【讨论】:

  • 我们可以在android java8中使用吗?
  • @ΦXocę웃Пepeúpaツ 如果它适用于 android,那么这取决于。尽管如此,使用 SimpleDateFormat ,你可以得到任何你想要的结果:)
  • java.time,Java 8 中出现的现代 Java 日期和时间 API,从 API 级别 26 开始内置在 Android 上。在较低的 API 级别上,您可以通过反向端口使用它,请参阅 @ 987654323@。 @ΦXocę웃Пepeúpaツ
  • @Ohados 现在清楚你真正想要什么,编辑了答案
猜你喜欢
  • 2017-05-23
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 2017-10-30
  • 1970-01-01
相关资源
最近更新 更多