Android / Java - 计算日期差异显示不同的结果

时间:2018-01-14 03:51:07

标签: java android date calendar

public long getDays(){
    Date today = new Date ( );
    Calendar cal = Calendar.getInstance (TimeZone.getTimeZone("GMT"));
    // Set as today
    cal.setTime ( today );
    System.out.println ( "Today Cal: "+cal.get ( Calendar.YEAR ) + "Y / " + ( cal.get ( Calendar.MONTH ) + 1 ) + "M / " + cal.get ( Calendar.DATE ) + " D" );
    Calendar cal2 = Calendar.getInstance (TimeZone.getTimeZone("GMT") );
   //Month has offset -1. June = 5
    cal2.set ( 2011, 5, 15 );//YY MM DD
    System.out.println ( "Start Day Cal2: "+cal2.get ( Calendar.YEAR ) + "Y / " + ( cal2.get ( Calendar.MONTH ) + 1 ) + "M / " + cal2.get ( Calendar.DATE ) + " D" );

    long count = 0;
    while ( !cal2.after ( cal ) ) {
        count++;
        //increment date
        cal2.add ( Calendar.DATE, 1 );
    }
    System.out.println ( "Ending Cal2: "+cal2.get ( Calendar.YEAR ) + "Y / " + ( cal2.get ( Calendar.MONTH ) + 1 ) + "M / " + cal2.get ( Calendar.DATE ) + " D" );

    return count;
}

这是我用来计算今天和2011年6月15日之间天数差异的代码。

这总是适用于Eclipse IDE,但是当我在Android上实现它时,它会随机显示2个不同的结果。

socket.h

大部分时间它显示2405,但有时显示2406 (虽然日期不应该改变,因为现在英国凌晨3点。)

Screenshot

这是System.out.println上显示的内容。 它具有相同的开始日期和结束日期,但是通过随机机会,而循环计数额外1。怎么样?

它只发生在Android上。 这是代码,显示如果文本视图有帮助,如何将其更新为小部件。

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    final int count = appWidgetIds.length;
    //Set Date Text
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.haruhi_widget);
    long days=getDays();
    remoteViews.setTextViewText(R.id.textView, days+context.getString(R.string.days));
    //Set ImageView
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inScaled = false;
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.haruhi1,options);
    remoteViews.setImageViewBitmap(R.id.imageView,bitmap);

    Intent intent = new Intent(context, HaruhiWidgetProvider.class);
    intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
    remoteViews.setOnClickPendingIntent(R.id.imageView, getPendingSelfIntent(context, KYON_KUN_DENWA));

    for (int i = 0; i < count; i++) {
      //  System.out.println(count+"appWidgetIds[i]");
        int widgetId = appWidgetIds[i];
        appWidgetManager.updateAppWidget(widgetId, remoteViews);
    }
}

1 个答案:

答案 0 :(得分:1)

TL;博士

ChronoUnit.DAYS.between( 
    LocalDate.of( 2011 , Month.JUNE , 15 ) , 
    LocalDate.now( ZoneId.of( "Africa/Tunis" ) )  
)

问题

当然看起来像是时区问题。我们无法确定,因为您没有向我们提供足够的信息,例如代码运行时使用的时区。

更重要的是,您正在使用多年前由java.time类过时的旧日期时间类。

并且您正在尝试使用日期与时间类一起使用仅限日期的值。

解决方案

  

计算今天和2011年6月15日之间天数的差异。

LocalDate类表示没有时间且没有时区的仅限日期的值。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

始终明确指定所需/预期的时区。省略区域意味着隐式应用JVM的当前默认时区。该默认值可能因机器而异,甚至可能在运行时(!)内发生变化。所以结果可能会有所不同。相反,始终传递可选的ZoneId参数。这样做的另一个好处是可以通过更多自我记录的代码来明确您的意图。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

获取2011年6月15日的日期。

LocalDate ld = LocalDate.of( 2011 , Month.JUNE , 15 ) ;

计算已用天数。

long days = ChronoUnit.DAYS.between( ld , today ) ;

关于java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?