在 Java 中减去两次
Subtracting Two Times in Java
之前我问过一个关于减去时间的问题,我以为我知道了。然而,当我调试时,出现了几个错误。基本上我要问的是创建一个打卡时钟,但我不能使用 Java 日历 API.
用户将输入开始时间和他们打卡的时间,它会计算时间之间的差异。
我的不太好用,我也不知道为什么。例如,如果 4:00am 是开始,12:00am 是结束,则返回 8 小时 00 分钟。那是不正确的。我以为我为可能性创建了一个 if 语句。
这是我的代码:
public static void elapsedTime()
{
Scanner reader = new Scanner (System.in);
System.out.print("Enter the beginning hour: ");
int startingHour = reader.nextInt();
System.out.print("Enter the beginning minute(s): ");
int startingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String startingTOD = reader.nextLine();
System.out.print("Enter the ending hour: ");
int endingHour = reader.nextInt();
System.out.print("Enter the ending minute(s): ");
int endingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String endingTOD = reader.nextLine();
System.out.println();
int hours;
int minutes = endingMin - startingMin;
String Am = "am" ;
String Pm = "pm" ;
if (endingTOD.equalsIgnoreCase(startingTOD) && minutes < 0 )
{
hours = (endingHour - startingHour) -1 ;
minutes = minutes + 60 ;
System.out.println(hours + " " + minutes);
}
else if (endingHour > startingHour&& endingTOD.equalsIgnoreCase(startingTOD) & minutes > 0 )
{
hours = endingHour - startingHour;
System.out.println(hours + " " + minutes);
}
else if (endingHour > startingHour && endingTOD.equalsIgnoreCase(startingTOD) && minutes == 0 )
{
hours = (endingHour-startingHour);
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (endingHour < startingHour && endingTOD.equalsIgnoreCase(startingTOD) && minutes == 0 )
{
hours = (endingHour-startingHour) + 12;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if ( endingHour==startingHour && minutes == 0)
{
hours = 12;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes > 0)
{
hours = (endingHour - startingHour) + 12;
System.out.println(hours + " " + minutes);
}
else if (( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes < 0)
{
hours = (endingHour - startingHour) -1 ;
minutes = minutes + 60 ;
System.out.println(hours + " " + minutes);
}
else if (endingHour > startingHour && ( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes == 0)
{
hours = (endingHour-startingHour) + 12;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (endingHour < startingHour &&( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes == 0)
{
hours = (endingHour - startingHour) +24;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (endingHour < startingHour &&( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes > 0)
{
hours = (endingHour - startingHour) + 2;
System.out.println(hours + " " + minutes);
}
}
鉴于您不能使用 Java 日历 API,您的方法虽然不是很模块化,但乍一看似乎不错。细节决定成败。
日期时间计算的技巧都是极端情况。这就是为什么没有人愿意写和维护这样的东西,甚至 Sun/Oracle 一次又一次地错了。
证明您的代码适用于所有条件将很难。您最好缩小范围并降低要求。 12 小时制还是 24 小时制?如果是 24 小时制,我们是从 0h 还是 1h 开始?我们跨越了几天?我们会被期望过午夜吗?等等
但是您的任务是以 12 或 24 为模的方式比较小时数(除非您的要求说您不必 "roll-over" 或跨越 12 或 24 小时边界。)真正的诀窍是将小时视为一系列栅栏帖子和 rails,并计算 rails。一次性错误将成为你在这里生存的祸根。
我的建议是至少使用 Java 日历 API 来仔细检查您的结果。
您可以利用内置的 Java 日期算术,而不是尝试重新发明轮子并自己实现日期减法逻辑,然后尝试涵盖所有极端情况。
像这样(将此代码复制到 TimeDifference.java 和 运行):
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Scanner;
import java.util.Calendar;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
public class TimeDifference {
public static void elapsedTime() {
Scanner reader = new Scanner(System.in);
System.out.print("Enter the beginning hour: ");
int startingHour = reader.nextInt();
System.out.print("Enter the beginning minute(s): ");
int startingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String startingTOD = reader.nextLine();
String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
// if no ids were returned, something is wrong. get out.
if (ids.length == 0)
System.exit(0);
// create a Pacific Standard Time time zone
SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
// set up rules for daylight savings time
pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY,
2 * 60 * 60 * 1000);
// create a GregorianCalendar with the Pacific Daylight time zone
// and the current date and time
Calendar startingCalendar = new GregorianCalendar(pdt);
Calendar endingCalendar = new GregorianCalendar(pdt);
Date trialTime = new Date();
startingCalendar.setTime(trialTime);
endingCalendar.setTime(trialTime);
startingCalendar.set(java.util.Calendar.HOUR, startingHour);
startingCalendar.set(java.util.Calendar.MINUTE, startingMin);
if (startingTOD.equalsIgnoreCase("AM")) {
startingCalendar.set(java.util.Calendar.AM_PM, 0);
} else if (startingTOD.equalsIgnoreCase("PM")) {
startingCalendar.set(java.util.Calendar.AM_PM, 1);
} else {
System.out.println("invalid starting AM/PM. exiting..");
System.exit(-1);
}
System.out.print("Enter the ending hour: ");
int endingHour = reader.nextInt();
System.out.print("Enter the ending minute(s): ");
int endingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String endingTOD = reader.nextLine();
System.out.println();
// get the supported ids for GMT-08:00 (Pacific Standard Time)
endingCalendar.set(java.util.Calendar.HOUR, endingHour);
endingCalendar.set(java.util.Calendar.MINUTE, endingMin);
if (endingTOD.equalsIgnoreCase("AM")) {
endingCalendar.set(java.util.Calendar.AM_PM, 0);
} else if (endingTOD.equalsIgnoreCase("PM")) {
endingCalendar.set(java.util.Calendar.AM_PM, 1);
} else {
System.out.println("invalid ending AM/PM. exiting..");
/* Exit program */
System.exit(-1);
}
long startingTimeMillis = startingCalendar.getTimeInMillis();
long endingTimeMillis = endingCalendar.getTimeInMillis();
long timeDifferenceMillis = endingTimeMillis - startingTimeMillis;
System.out.println(String.format("Time difference between starting and ending time (in minutes and hours): %d hours, %d minutes",
TimeUnit.MILLISECONDS.toHours(timeDifferenceMillis),
TimeUnit.MILLISECONDS.toMinutes(timeDifferenceMillis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeDifferenceMillis))
));
reader.close();
}
public static void main(String[] args) {
elapsedTime();
}
}
之前我问过一个关于减去时间的问题,我以为我知道了。然而,当我调试时,出现了几个错误。基本上我要问的是创建一个打卡时钟,但我不能使用 Java 日历 API.
用户将输入开始时间和他们打卡的时间,它会计算时间之间的差异。
我的不太好用,我也不知道为什么。例如,如果 4:00am 是开始,12:00am 是结束,则返回 8 小时 00 分钟。那是不正确的。我以为我为可能性创建了一个 if 语句。
这是我的代码:
public static void elapsedTime()
{
Scanner reader = new Scanner (System.in);
System.out.print("Enter the beginning hour: ");
int startingHour = reader.nextInt();
System.out.print("Enter the beginning minute(s): ");
int startingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String startingTOD = reader.nextLine();
System.out.print("Enter the ending hour: ");
int endingHour = reader.nextInt();
System.out.print("Enter the ending minute(s): ");
int endingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String endingTOD = reader.nextLine();
System.out.println();
int hours;
int minutes = endingMin - startingMin;
String Am = "am" ;
String Pm = "pm" ;
if (endingTOD.equalsIgnoreCase(startingTOD) && minutes < 0 )
{
hours = (endingHour - startingHour) -1 ;
minutes = minutes + 60 ;
System.out.println(hours + " " + minutes);
}
else if (endingHour > startingHour&& endingTOD.equalsIgnoreCase(startingTOD) & minutes > 0 )
{
hours = endingHour - startingHour;
System.out.println(hours + " " + minutes);
}
else if (endingHour > startingHour && endingTOD.equalsIgnoreCase(startingTOD) && minutes == 0 )
{
hours = (endingHour-startingHour);
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (endingHour < startingHour && endingTOD.equalsIgnoreCase(startingTOD) && minutes == 0 )
{
hours = (endingHour-startingHour) + 12;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if ( endingHour==startingHour && minutes == 0)
{
hours = 12;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes > 0)
{
hours = (endingHour - startingHour) + 12;
System.out.println(hours + " " + minutes);
}
else if (( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes < 0)
{
hours = (endingHour - startingHour) -1 ;
minutes = minutes + 60 ;
System.out.println(hours + " " + minutes);
}
else if (endingHour > startingHour && ( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes == 0)
{
hours = (endingHour-startingHour) + 12;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (endingHour < startingHour &&( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes == 0)
{
hours = (endingHour - startingHour) +24;
minutes = 0;
System.out.println(hours + " " + minutes);
}
else if (endingHour < startingHour &&( endingTOD.equalsIgnoreCase(Pm) && startingTOD.equalsIgnoreCase(Am)) && minutes > 0)
{
hours = (endingHour - startingHour) + 2;
System.out.println(hours + " " + minutes);
}
}
鉴于您不能使用 Java 日历 API,您的方法虽然不是很模块化,但乍一看似乎不错。细节决定成败。
日期时间计算的技巧都是极端情况。这就是为什么没有人愿意写和维护这样的东西,甚至 Sun/Oracle 一次又一次地错了。
证明您的代码适用于所有条件将很难。您最好缩小范围并降低要求。 12 小时制还是 24 小时制?如果是 24 小时制,我们是从 0h 还是 1h 开始?我们跨越了几天?我们会被期望过午夜吗?等等
但是您的任务是以 12 或 24 为模的方式比较小时数(除非您的要求说您不必 "roll-over" 或跨越 12 或 24 小时边界。)真正的诀窍是将小时视为一系列栅栏帖子和 rails,并计算 rails。一次性错误将成为你在这里生存的祸根。
我的建议是至少使用 Java 日历 API 来仔细检查您的结果。
您可以利用内置的 Java 日期算术,而不是尝试重新发明轮子并自己实现日期减法逻辑,然后尝试涵盖所有极端情况。
像这样(将此代码复制到 TimeDifference.java 和 运行):
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Scanner;
import java.util.Calendar;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
public class TimeDifference {
public static void elapsedTime() {
Scanner reader = new Scanner(System.in);
System.out.print("Enter the beginning hour: ");
int startingHour = reader.nextInt();
System.out.print("Enter the beginning minute(s): ");
int startingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String startingTOD = reader.nextLine();
String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
// if no ids were returned, something is wrong. get out.
if (ids.length == 0)
System.exit(0);
// create a Pacific Standard Time time zone
SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
// set up rules for daylight savings time
pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY,
2 * 60 * 60 * 1000);
// create a GregorianCalendar with the Pacific Daylight time zone
// and the current date and time
Calendar startingCalendar = new GregorianCalendar(pdt);
Calendar endingCalendar = new GregorianCalendar(pdt);
Date trialTime = new Date();
startingCalendar.setTime(trialTime);
endingCalendar.setTime(trialTime);
startingCalendar.set(java.util.Calendar.HOUR, startingHour);
startingCalendar.set(java.util.Calendar.MINUTE, startingMin);
if (startingTOD.equalsIgnoreCase("AM")) {
startingCalendar.set(java.util.Calendar.AM_PM, 0);
} else if (startingTOD.equalsIgnoreCase("PM")) {
startingCalendar.set(java.util.Calendar.AM_PM, 1);
} else {
System.out.println("invalid starting AM/PM. exiting..");
System.exit(-1);
}
System.out.print("Enter the ending hour: ");
int endingHour = reader.nextInt();
System.out.print("Enter the ending minute(s): ");
int endingMin = reader.nextInt();
System.out.print("Enter AM/PM: ");
reader.nextLine();
String endingTOD = reader.nextLine();
System.out.println();
// get the supported ids for GMT-08:00 (Pacific Standard Time)
endingCalendar.set(java.util.Calendar.HOUR, endingHour);
endingCalendar.set(java.util.Calendar.MINUTE, endingMin);
if (endingTOD.equalsIgnoreCase("AM")) {
endingCalendar.set(java.util.Calendar.AM_PM, 0);
} else if (endingTOD.equalsIgnoreCase("PM")) {
endingCalendar.set(java.util.Calendar.AM_PM, 1);
} else {
System.out.println("invalid ending AM/PM. exiting..");
/* Exit program */
System.exit(-1);
}
long startingTimeMillis = startingCalendar.getTimeInMillis();
long endingTimeMillis = endingCalendar.getTimeInMillis();
long timeDifferenceMillis = endingTimeMillis - startingTimeMillis;
System.out.println(String.format("Time difference between starting and ending time (in minutes and hours): %d hours, %d minutes",
TimeUnit.MILLISECONDS.toHours(timeDifferenceMillis),
TimeUnit.MILLISECONDS.toMinutes(timeDifferenceMillis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeDifferenceMillis))
));
reader.close();
}
public static void main(String[] args) {
elapsedTime();
}
}