Android 来自字符串的日历对象
Android calendar object from string
我想为我的 android 应用创建一个函数,我在其中传递 3 个变量
- 发件人(表示日期的字符串)
- 收件人(表示日期的字符串)
- 单位(整数)
结果应该是这两个日期的差异,以周、天或年为单位,具体取决于单位。这是我的代码:
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);
如果数据示例采用这种格式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
只需使用 Joda 时间
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
java.time
旧版日期时间 API(java.util
日期时间类型及其格式类型,SimpleDateFormat
)已过时且容易出错。建议完全停止使用,改用java.time
,modern 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
allows specifying optional patterns using square brackets. Alternatively, it can be done with the help of DateTimeFormatterBuilder#optionalStart
and DateTimeFormatterBuilder#optionalEnd
.
从 Trail: Date Time[=47= 中了解有关 modern date-time API* 的更多信息].
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and 。
我想为我的 android 应用创建一个函数,我在其中传递 3 个变量
- 发件人(表示日期的字符串)
- 收件人(表示日期的字符串)
- 单位(整数)
结果应该是这两个日期的差异,以周、天或年为单位,具体取决于单位。这是我的代码:
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);
如果数据示例采用这种格式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
只需使用 Joda 时间
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
java.time
旧版日期时间 API(java.util
日期时间类型及其格式类型,SimpleDateFormat
)已过时且容易出错。建议完全停止使用,改用java.time
,modern 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
allows specifying optional patterns using square brackets. Alternatively, it can be done with the help of DateTimeFormatterBuilder#optionalStart
and DateTimeFormatterBuilder#optionalEnd
.
从 Trail: Date Time[=47= 中了解有关 modern date-time API* 的更多信息].
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and