【问题标题】:toString() returns unexpected things on a Date objecttoString() 在 Date 对象上返回意外的东西
【发布时间】:2018-08-16 10:20:29
【问题描述】:

我最近开始使用 Android Studio 3.1.2 和 SDK 19 编写我真正的第一个 Android 项目。

我的一个对象具有日期属性。在某些时候,我想在 TextView 中显示整个日期时间或部分时间。所以我尝试了菜鸟的方式,并在我的日期上调用了 toString()。 但是,显示的文本包含我在用于创建日期对象的 SingleDateFormat 模式中未定义的元素。

这就是我在 myObject 上创建日期的方式:

Date date1;
Date date2;

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

try {
    date1 = format.parse(json.getString("date_1"));
    dtae2 = format.parse(json.getString("date_2"));
} catch(ParseException e) {
    //error handling stuff
    e.printStackTrace();
}

这是我想在视图上显示日期的地方:

myTextView.setText("First appearance logged at " + myObject.getDate1().toString());

我希望显示像 2018-08-16 12:14:42 这样的字符串。相反,我得到的是Thu Aug 12:14:42 GMT +02:00 2018。这似乎是另一个 DateFormat 并忽略了我的自定义模式。

所以我的问题是,如果有办法操纵 toString() 的输出,那么日期会以我在模式中定义的方式显示。我可以以某种方式将模式传递给 toString() 方法吗?

编辑

我将我的对象的属性更改为字符串类型,尽管它更容易呈现。将它们转换为日期的原因是,我需要计算两个人之间的持续时间,但这不是我无法解决的问题。感谢社区。​​p>

【问题讨论】:

  • 要真正回答您的问题,请将 SimpleDateFormat 子类化并覆盖 toString 函数。我个人不会这样做,因为有更简单的方法可以实现您想要实现的目标
  • @InsaneCat 我相信提问者将能够找到所有答案,包括您的答案,而无需这些 cmets 的参考。您的评论带有攻击性气味,您可以将其删除。
  • 顺便考虑扔掉长期过时且臭名昭著的麻烦SimpleDateFormat和朋友,并将ThreeTenABP添加到您的Android项目中,以便使用java.time,现代Java日期和时间API .使用起来感觉好多了。
  • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的旧日期时间类现在已被 java.time 类所取代。许多 java.time 功能在ThreeTen-Backport 项目中被反向移植到Java 6 和Java 7。在ThreeTenABP 项目中进一步适用于早期的Android。见How to use ThreeTenABP…

标签: android date tostring


【解决方案1】:

根据您的需要,您可以使用json.getString("date_1")

您不需要设置额外的逻辑。当您想将String 日期转换为Date 对象进行某些计算时,需要进行解析。

如果您想更改接收日期的格式,请使用此方法。

changeStringDateFormat(json.getString("date_1"), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");

只需将此方法放入 Util 中即可。

public String changeStringDateFormat(String date, String inputDateFormat, String outPutDateFormat) {
    Date initDate = null;
    try {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(inputDateFormat);
        initDate = simpleDateFormat.parse(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    SimpleDateFormat outputFormatter = new SimpleDateFormat(outPutDateFormat);
    String parsedDate = outputFormatter.format(initDate);
    return parsedDate;
}

Java Date Doc,它从默认格式返回字符串。

公共字符串 toString()

将此 Date 对象转换为以下形式的字符串:

dow mon dd hh:mm:ss zzz yyyy

【讨论】:

  • 我认为这导致了我想到的解决方案。扭曲是我需要它们作为 Date 对象 t 稍后计算这两个家伙之间的差异,然后我实际上只是从 json 传递字符串。
  • 好的,那就用json.getString("date_1")来显示,你的解析方法是正确的。此外 toString() 不会以您想要的格式返回。如果要获取字符串日期,则必须再次从日期解析日期。
  • 因为我现在在 SimpleDateFormat.format() 上遇到 NullPointerException,我会尝试你的建议:D
  • 通过一些小的或更大的解决方法,这对我有用
  • 我认为你不必做额外的努力,显示你的代码,我会更新它。
【解决方案2】:

只需编写这段代码sn-p

JAVA 文件

 public class MainActivity extends AppCompatActivity {
    TextView my_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        my_text = findViewById(R.id.my_text);

        String pattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        String date = simpleDateFormat.format(new Date());
        Toast.makeText(getApplicationContext(), "" + date, Toast.LENGTH_SHORT).show();
        my_text.setText("Your Date is :  " + date);
    }
}

XML 文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="mydemo.com.anew.MainActivity">

    <TextView
        android:id="@+id/my_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

查看输出:

查看与您的要求相同的输出屏幕截图获取当前日期:

参考这个Tutorial

希望对你有帮助

【讨论】:

  • 似乎我的架构有点令人窒息,但我现在了解 DateFormat.format 方法的工作原理,所以它实际上对我很有帮助
  • 很高兴阻止你 :) @Procra
【解决方案3】:

tl;博士

使用现代的 java.time 类,而不是可怕的遗留 DateSimpleDateFormat 类。

myJavaUtilDate          // Never use `java.util.Date`.
.toInstant()            // Convert from legacy class to modern replacement. Returns a `Instant` object, a moment in UTC.
.atOffset(              // Convert from the basic `Instant` class to the more flexible `OffsetDateTime` class.
    ZoneOffset.UTC      // Constant defining an offset-from-UTC of zero, UTC itself.
)                       // Returns a `OffsetDateTime` object.
.format(                // Generate a `String` with text representing the value of this `OffsetDateTime` object.
    DateTimeFormatter.ISO_LOCAL_DATE_TIME  // Pre-defined formatter stored in this constant. 
)                       // Returns a `String` object.
.replace( "T" , " " )   // Replace the standard `T` in the middle with your desired SPACE character.

2018-08-16 10:14:42

java.time

您正在使用多年前被 java.time 类取代的糟糕的旧类。

如果传递了java.util.Date 对象,立即转换为java.time.Instant。两者都代表 UTC 中的一个时刻。 Instant 具有比毫秒更精细的纳秒分辨率。

要在旧类和现代类之间进行转换,请查看添加到旧类的新转换方法。

Instant

Instant instant = myJavaUtilDate.toInstant() ;  // New method on old class for converting to/from java.time classes.

ISO 8601

要生成String,其中包含与您所需格式相似的标准ISO 8601 格式的文本,请调用toString

String output = instant.toString() ;  // Generate text in standard ISO 8601 format.

经过的时间 = Duration

顺便说一下,要计算经过的时间,请使用 Duration 类。传递一对Instant 对象来计算经过的24 小时“天”、小时、分钟和秒数。

Duration d = Duration.between( start , stop ) ;  // Calc elapsed time.

2018-08-16T10:14:42Z

OffsetDateTime

对于其他格式,从基本的Instant 类转换为更灵活的OffsetDateTime 类。

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

odt.toString(): 2018-08-16T10:14:42Z

DateTimeFormatter

您想要的格式接近预定义的格式化程序DateTimeFormatter.ISO_LOCAL_DATE_TIME。只需将中间的T 替换为空格即可。

String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
                   .replace( "T" , " " ) ;

2018-08-16 10:14:42

ZonedDateTime

请记住,到目前为止,我们只关注 UTC。对于任何给定的时刻,日期和时间在全球各地都因区域而异。

如果您想通过某个地区(某个时区)的人们使用的挂钟时间的镜头看到同一时刻,则应用ZoneId 来获取ZonedDateTime 对象。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString(): 2018-08-16T11:14:42+01:00[非洲/突尼斯]

您可以使用与上面相同的格式化程序来生成所需格式的字符串。

String output = zdt.format( f ) ;

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案4】:

    您需要像这样使用 SimpleDateFormat

    String myFormat = "yyyy-MM-dd HH:mm:ss";
    SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
    myTextView.setText("First appearance logged at " + sdf.format(date1));
    

    【讨论】:

    • 这只会删除 GMT 部分,我还希望月份显示为数字并省略星期几
    【解决方案5】:

    在我的项目中,我一直在使用 format() 函数进行格式化,如下所示:

    myTextView.setText("First appearance logged at " + format.format(myObject.getData1()));

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 2010-09-27
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多