/* * This is free and unencumbered software released into the public domain. * * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * For more information, please refer to <http://unlicense.org/> */ package jxtn.core.unix; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZoneOffset; /** * {@codse struct timespec} * * @author aqd */ public final class Timespec implements Comparable<Timespec> { public final long tv_sec; public final long tv_nsec; Timespec(ByteBuffer buffer) { buffer.order(ByteOrder.nativeOrder()); this.tv_sec = buffer.getLong(); this.tv_nsec = buffer.getLong(); } public DateInfo toDateInfo() { return new DateInfo(this.tv_sec); } public TimeInfo toTimeInfo() { return new TimeInfo(this.tv_sec, this.tv_nsec); } @Override public int compareTo(Timespec other) { long sec_diff = this.tv_sec - other.tv_sec; if (sec_diff > 0) { return 1; } else if (sec_diff < 0) { return -1; } long nsec_diff = this.tv_nsec - other.tv_nsec; if (nsec_diff > 0) { return 1; } else if (nsec_diff < 0) { return -1; } return 0; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null || this.getClass() != obj.getClass()) { return false; } return this.equals((Timespec) obj); } public boolean equals(Timespec other) { if (other == this) { return true; } if (other == null) { return false; } return this.tv_sec == other.tv_sec && this.tv_nsec == other.tv_nsec; } @Override public int hashCode() { int hash = 5; hash = 17 * hash + (int) (this.tv_sec); hash = 17 * hash + (int) (this.tv_nsec); return hash; } public LocalDateTime toLocalDateTime() { return LocalDateTime.ofEpochSecond(this.tv_sec, (int) this.tv_nsec, ZoneOffset.UTC); } public OffsetDateTime toOffsetDateTime() { return OffsetDateTime.of(this.toLocalDateTime(), ZoneOffset.UTC); } @Override public String toString() { return this.toDateInfo() + "T" + this.toTimeInfo() + "Z"; } public static final class DateInfo { public final int year; public final int month; public final int day; public DateInfo(long seconds) { int epochDays = (int) (seconds / 86400L); epochDays += 719468; int era = (epochDays >= 0 ? epochDays : epochDays - 146096) / 146097; int dayOfEra = epochDays - era * 146097; int yearOfEra = (dayOfEra - dayOfEra / 1460 + dayOfEra / 36524 - dayOfEra / 146096) / 365; int y = yearOfEra + era * 400; int dayOfYear = dayOfEra - (365 * yearOfEra + yearOfEra / 4 - yearOfEra / 100); int mp = (5 * dayOfYear + 2) / 153; int d = dayOfYear - (153 * mp + 2) / 5 + 1; int m = mp + (mp < 10 ? 3 : -9); this.year = y + (m <= 2 ? 1 : 0); this.month = m; this.day = d; } @Override public String toString() { StringBuilder sb = new StringBuilder("2015-10-29".length()); sb.append(StringFormat.padLeft(String.valueOf(this.year), 4, '0')); sb.append('-'); sb.append(StringFormat.padLeft(String.valueOf(this.month), 2, '0')); sb.append('-'); sb.append(StringFormat.padLeft(String.valueOf(this.day), 2, '0')); return sb.toString(); } } public static final class TimeInfo { public final int hour; public final int minute; public final int second; public final int millisecond; public TimeInfo(long seconds, long nanoseconds) { this.millisecond = (int) (nanoseconds / 1000000L); int remainingSeconds = (int) (seconds % 86400L); this.hour = remainingSeconds / 3600; remainingSeconds -= this.hour * 3600; this.minute = remainingSeconds / 60; remainingSeconds -= this.minute * 60; this.second = remainingSeconds; } @Override public String toString() { StringBuilder sb = new StringBuilder("19:21:52.891".length()); sb.append(StringFormat.padLeft(String.valueOf(this.hour), 2, '0')); sb.append(':'); sb.append(StringFormat.padLeft(String.valueOf(this.minute), 2, '0')); sb.append(':'); sb.append(StringFormat.padLeft(String.valueOf(this.second), 2, '0')); sb.append('.'); sb.append(StringFormat.padLeft(String.valueOf(this.millisecond), 3, '0')); return sb.toString(); } } }