来自字符串的Android日历对象

时间:2016-04-18 11:22:01

标签: java android datetime-format android-calendar

我想为我的Android应用程序创建一个函数,我传递3个变量

  1. From(表示日期的字符串)
  2. To(表示日期的字符串)
  3. 单位(整数)
  4. 结果应该是,这两个日期的差异在几周,或几天或几年,具体取决于单位。这是我的代码:

     private int datesDifference(String from, String to, int unit){
       Calendar from_date = Calendar.getInstance();
       Calendar to_date = Calendar.getInstance();
       DebugLogger.debug("From date = "+from+" to date = "+to);
    
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMM-dd", Locale.getDefault());
       try {
           from_date.setTime(sdf.parse(from));
           to_date.setTime(sdf.parse(to));
       } catch (ParseException e) {
           e.printStackTrace();
       }
    
       int from_year = from_date.get(Calendar.YEAR);
       int from_month = from_date.get(Calendar.MONTH)+1;
       int from_day = from_date.get(Calendar.DAY_OF_MONTH);
       DebugLogger.debug("from_year "+from_year+" from month "+from_month+" from day "+from_day);
    
       int to_year = to_date.get(Calendar.YEAR);
       int to_month = to_date.get(Calendar.MONTH)+1;
       int to_day = to_date.get(Calendar.DAY_OF_MONTH);
       DebugLogger.debug("to_year "+to_year+" to month "+to_month+" to day "+to_day);
    
    
       from_date.set(from_year, from_month, from_day);//set begin_of_goal_date
       to_date.set(to_year, to_month, to_day);//set now_date
    
       if(unit==0){
           //TODO unit for days difference
           return 0;
       }else if(unit==1){
           //TODO unit for week difference
           long milliseconds1 = from_date.getTimeInMillis();
           long milliseconds2 = to_date.getTimeInMillis();
           long diff = milliseconds2 - milliseconds1;
           long diffWeeks = diff / (7*24 * 60 * 60 * 1000);
           int weeks = (int) diffWeeks;
           DebugLogger.debug("Difference in weeks "+weeks);
           return weeks;
       }else{
           //TODO unit for years difference
           return 0;
       }
    

    }

    上面的代码无法正常工作,因为它不会将日期作为日历对象,而是取代今天的from_date和to_date!我的代码出了什么问题?

    更新

    这是我在函数中传递的数据

        String begin_of_goal_date="2016-01-20";//when we changed the goal
        String now_date="2016-04-18";//now
        int weeks = datesDifference(begin_of_goal_date,now_date,1);
    

3 个答案:

答案 0 :(得分:2)

如果数据示例采用此格式2016-01-20

SimpleDateFormat格式从yyyy-MMM-dd更改为yyyy-MM-dd

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());

通过此电话:

datesDifference("2016-01-01", "2016-02-01", 1);

<强>输出

From date = 2016-01-01 to date = 2016-02-01
from_year 2016 from month 1 from day 1
to_year 2016 to month 2 to day 1
Difference in weeks 4

用你的例子:

String begin_of_goal_date="2016-01-20";//when we changed the goal
String now_date="2016-04-18";//now
int weeks = datesDifference(begin_of_goal_date,now_date,1);

<强>输出:

From date = 2016-01-20 to date = 2016-04-18
from_year 2016 from month 1 from day 20
to_year 2016 to month 4 to day 18
Difference in weeks 12

答案 1 :(得分:1)

java.time

旧的日期时间 API(java.util 日期时间类型及其格式类型 SimpleDateFormat)已过时且容易出错。建议完全停止使用,改用java.timemodern date-time API*

使用现代 API 的解决方案:

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getDuration("2020-05-05", "2021-05-07", ChronoUnit.YEARS));
        System.out.println(getDuration("2020-05-05", "2021-05-07", ChronoUnit.MONTHS));
        System.out.println(getDuration("2020-05-05", "2021-05-07", ChronoUnit.DAYS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.YEARS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.MONTHS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.DAYS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.HOURS));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.MINUTES));
        System.out.println(getDuration("2020-05-05 10:20:30", "2021-05-07 5:10:15", ChronoUnit.SECONDS));
        System.out.println(getDuration("5:10:15", "10:20:30", ChronoUnit.HOURS));
        System.out.println(getDuration("5:10:15", "10:20:30", ChronoUnit.MINUTES));
        System.out.println(getDuration("5:10:15", "10:20:30", ChronoUnit.SECONDS));
    }

    public static long getDuration(String from, String to, ChronoUnit unit) {
        ZonedDateTime zdt = LocalDate.now().atStartOfDay(ZoneId.systemDefault());
        
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .appendPattern("[u-M-d][ ][H[:m[:s]]]")
                                .parseDefaulting(ChronoField.YEAR, zdt.getYear())
                                .parseDefaulting(ChronoField.MONTH_OF_YEAR, zdt.getMonthValue())
                                .parseDefaulting(ChronoField.DAY_OF_MONTH, zdt.getDayOfMonth())
                                .parseDefaulting(ChronoField.HOUR_OF_DAY, zdt.getHour())
                                .parseDefaulting(ChronoField.MINUTE_OF_HOUR, zdt.getMinute())
                                .parseDefaulting(ChronoField.SECOND_OF_MINUTE, zdt.getSecond()) 
                                .parseDefaulting(ChronoField.NANO_OF_SECOND, zdt.getNano()) 
                                .toFormatter(Locale.ENGLISH)
                                .withZone(ZoneId.systemDefault());
        
        return unit.between(ZonedDateTime.parse(from, dtf), ZonedDateTime.parse(to, dtf));
    }
}

输出:

1
12
367
1
12
366
8802
528169
31690185
5
310
18615

请注意,DateTimeFormatter 允许使用方括号指定可选模式。或者,它可以在 DateTimeFormatterBuilder#optionalStartDateTimeFormatterBuilder#optionalEnd 的帮助下完成。

modern date-time API 中了解有关 Trail: Date Time* 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

答案 2 :(得分:0)

只需使用Joda Time

Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

http://joda-time.sourceforge.net/faq.html#datediff