IMPORTANT: external libraries, Date and Instant class are not allowed
You may not use any library routines for manipulation of time or dates, such as converting UNIX time to a date string or for formatting date strings in general. All calculations for determining year, month, day, and time must appear in your source.
I wrote this program to convert from UNIX time (time in seconds since 12:00 AM January 1, 1970) to normal date and time. At first glance it seems to work fine, but in some tests it was off by exactly one day. The hours, minutes, months, and years are always correct, but the days are one too few.
For example, when using UNIX time 1234567890 the program produces 11:31 PM 02/13/2009, which is correct! However when inputing 1111111111 (10 1's), the program produces 1:58 AM 03/17/2005, where it should output 01:58 AM 03/18/2005. 64075132196 produces 7:49 AM 06/17/4000 (correct) but 95632040996 produces 7:49 AM 06/16/5000, where it should be the 17th day instead of the 16th.
In order to check my program, I entered a date and time into https://www.unixtimestamp.com/ and entered the resulting UNIX time into my program. (This is how I managed to get exact UNIX codes in the troubleshooting above).
I would appreciate help finding this error and additionally implementing a more efficient solution to this problem altogether.
import java.util.*;
class Main {
public static void main(String[] args) {
System.out.println("\nEnter UNIX time");
Scanner scan = new Scanner(System.in);
int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int[] leapYearMonthDays = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
long unix = scan.nextLong();
int years = 0, months = 0, days = 0, hours = 0, minutes = 0;
boolean leapYear = false;
String AMPM = "AM";
while (unix >= 60) {
unix -= 60;
minutes ;
if (minutes >= 60) {
minutes -= 60;
hours ;
}
if (hours >= 24) {
hours -= 24;
days ;
}
if (leapYear) {
if (days >= leapYearMonthDays[months]) {
days -= leapYearMonthDays[months];
months ;
}
}
else {
if (days >= monthDays[months]) {
days -= monthDays[months];
months ;
}
}
if (months >= 12) {
if (isLeapYear(1970 years)) leapYear = true; else leapYear = false;
months -= 12;
years ;
}
}
if (hours > 12) {
AMPM = "PM";
hours -= 12;
}
if (days == 0) days = 1;
String daysString = String.valueOf(days);
if (daysString.length() == 1) daysString = "0" daysString;
String monthsString = String.valueOf(months 1);
if (monthsString.length() == 1) monthsString = "0" monthsString;
String minutesString = String.valueOf(minutes);
if (minutesString.length() == 1) minutesString = "0" minutesString;
if (hours == 0) hours = 12;
System.out.println("\n" hours ":" minutesString " " AMPM " " monthsString "/" daysString "/" (years 1970));
}
public static boolean isLeapYear (int year) {
if (year % 4 == 0) {
if (year % 100 == 0) {
if (year % 400 == 0) {
return true;
}
else return false;
}
else return true;
}
return false;
}
}
CodePudding user response:
You created your own code. That probably was the intent of the homework. Now pinpoint the problem.
For that you can actually create a loop generating different Unix time values.
For each of these values calculate the date using your code, in parallel calculate the date using java.util.Date
or java.util.Instant
. Compare the dates and print results suitable so you can pinpoint the situations where your code produces deviations. Try to understand the deviations and improve your code.
With that you would not only exercise coding date calculations but also automated testing or test driven development.
CodePudding user response:
Given
UNIX time (time in seconds since 12:00 AM January 1, 1970)
Assume if we convert 0
as integer timestmap in unix-epoch format to a java.util.Date
we solved it.
Using java.util.Date
(prior to Java 8)
long unixTimeInMilliseconds = 0;
Date convertedDate = new java.util.Date(unixTimeInMilliseconds);
System.out.println(convertedDate);
Prints:
Thu Jan 01 00:00:00 GMT 1970
Using java.time.Instant
or suitable Java 8 class
You can also use the Java Date/Time API introduced since Java 8 in a similar manner:
long unixTimeInMilliseconds = 0; // 0 ms
Instant timestamp = Instant.ofEpochMilli(unixTimeInMilliseconds);
System.out.println(timestamp);
Prints:
1970-01-01T00:00:00Z