/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.HLE.kernel.types;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class ScePspDateTime extends pspAbstractMemoryMappedStructure {
public static final TimeZone GMT = TimeZone.getTimeZone("GMT");
public static final int SIZEOF = 16;
public int year;
public int month;
public int day;
public int hour;
public int minute;
public int second;
public int microsecond;
/** All fields will be initialised to the time the object was created. */
public ScePspDateTime() {
Calendar cal = Calendar.getInstance();
year = cal.get(Calendar.YEAR);
month = 1 + cal.get(Calendar.MONTH);
day = cal.get(Calendar.DAY_OF_MONTH);
hour = cal.get(Calendar.HOUR_OF_DAY);
minute = cal.get(Calendar.MINUTE);
second = cal.get(Calendar.SECOND);
microsecond = cal.get(Calendar.MILLISECOND) * 1000;
}
public ScePspDateTime(int timezone) {
Calendar cal = Calendar.getInstance();
int minutes = timezone;
int hours = 0;
while(minutes > 59) {
hours++;
minutes -= 60;
}
String timeString = String.format("UTC+%02d%02d", hours, minutes);
TimeZone tz = TimeZone.getTimeZone(timeString);
cal.setTimeZone(tz);
year = cal.get(Calendar.YEAR);
month = 1 + cal.get(Calendar.MONTH);
day = cal.get(Calendar.DAY_OF_MONTH);
hour = cal.get(Calendar.HOUR_OF_DAY);
minute = cal.get(Calendar.MINUTE);
second = cal.get(Calendar.SECOND);
microsecond = cal.get(Calendar.MILLISECOND) * 1000;
}
public ScePspDateTime(int year, int month, int day,
int hour, int minute, int second, int microsecond) {
this.year = year;
this.month = month;
this.day = day;
this.hour = hour;
this.minute = minute;
this.second = second;
this.microsecond = microsecond;
}
/** @param time MSDOS time, seconds since the epoch/1980. */
public static ScePspDateTime fromMSDOSTime(long time) {
// Calculate each time parameter.
long milliseconds = time / 10000;
long days = milliseconds / (24 * 60 * 60 * 1000);
milliseconds -= days * (24 * 60 * 60 * 1000);
long hours = milliseconds / (60 * 60 * 1000);
milliseconds -= hours * (60 * 60 * 1000);
long minutes = milliseconds / (60 * 1000);
milliseconds -= minutes * (60 * 1000);
long seconds = milliseconds / 1000;
milliseconds -= seconds * 1000;
// Initialize a new calendar and set it for the rigth epoch.
Calendar cal = Calendar.getInstance();
cal.set(1980, Calendar.JANUARY, 1, 0, 0, 0);
cal.add(Calendar.DATE, (int)days);
cal.add(Calendar.HOUR_OF_DAY, (int)hours);
cal.add(Calendar.MINUTE, (int)minutes);
cal.add(Calendar.SECOND, (int)seconds);
cal.add(Calendar.MILLISECOND, (int)milliseconds);
int year = cal.get(Calendar.YEAR);
int month = 1 + cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
int microsecond = cal.get(Calendar.MILLISECOND) * 1000;
return new ScePspDateTime(year, month, day, hour, minute, second, microsecond);
}
/** @param time FILETIME time, 100 nanoseconds since the epoch/1601. */
public static ScePspDateTime fromFILETIMETime(long time) {
// Calculate each time parameter.
long milliseconds = time / 10000;
long days = milliseconds / (24 * 60 * 60 * 1000);
milliseconds -= days * (24 * 60 * 60 * 1000);
long hours = milliseconds / (60 * 60 * 1000);
milliseconds -= hours * (60 * 60 * 1000);
long minutes = milliseconds / (60 * 1000);
milliseconds -= minutes * (60 * 1000);
long seconds = milliseconds / 1000;
milliseconds -= seconds * 1000;
// Initialize a new calendar and set it for the rigth epoch.
Calendar cal = Calendar.getInstance();
cal.set(1601, Calendar.JANUARY, 1, 0, 0, 0);
cal.add(Calendar.DATE, (int)days);
cal.add(Calendar.HOUR_OF_DAY, (int)hours);
cal.add(Calendar.MINUTE, (int)minutes);
cal.add(Calendar.SECOND, (int)seconds);
cal.add(Calendar.MILLISECOND, (int)milliseconds);
int year = cal.get(Calendar.YEAR);
int month = 1 + cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
int microsecond = cal.get(Calendar.MILLISECOND) * 1000;
return new ScePspDateTime(year, month, day, hour, minute, second, microsecond);
}
/** @param time Unix time, seconds since the epoch/1970. */
public static ScePspDateTime fromUnixTime(long time) {
Calendar cal = Calendar.getInstance();
Date date = new Date(time);
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = 1 + cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
int microsecond = cal.get(Calendar.MILLISECOND) * 1000;
return new ScePspDateTime(year, month, day, hour, minute, second, microsecond);
}
/** @param microseconds */
public static ScePspDateTime fromMicros(long micros) {
Calendar cal = Calendar.getInstance(GMT);
Date date = new Date(micros / 1000L);
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = 1 + cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
int microsecond = (int)(micros % 1000000L);
return new ScePspDateTime(year, month, day, hour, minute, second, microsecond);
}
@Override
protected void read() {
year = read16();
month = read16();
day = read16();
hour = read16();
minute = read16();
second = read16();
microsecond = read32();
}
@Override
protected void write() {
write16((short) year);
write16((short) month);
write16((short) day);
write16((short) hour);
write16((short) minute);
write16((short) second);
write32(microsecond);
}
@Override
public int sizeof() {
return SIZEOF;
}
@Override
public String toString() {
return String.format("%04d-%02d-%02d %02d:%02d:%02d micros=%d", year, month, day, hour, minute, second, microsecond);
}
}