/* * This file is part of Skript. * * Skript 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. * * Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>. * * * Copyright 2011-2014 Peter Güttinger * */ package ch.njol.skript.util; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.Skript; import ch.njol.skript.localization.Message; import ch.njol.util.Math2; import ch.njol.yggdrasil.YggdrasilSerializable; /** * @author Peter Güttinger */ public class Time implements YggdrasilSerializable { private final static int TICKS_PER_HOUR = 1000, TICKS_PER_DAY = 24 * TICKS_PER_HOUR; private final static double TICKS_PER_MINUTE = 1000. / 60; /** * 0 ticks == 6:00 */ private final static int HOUR_ZERO = 6 * TICKS_PER_HOUR; private final int time; public Time() { time = 0; } public Time(final int time) { this.time = Math2.mod(time, TICKS_PER_DAY); } /** * @return Ticks in Minecraft time (0 ticks == 6:00) */ public int getTicks() { return time; } /** * @return Ticks in day time (0 ticks == 0:00) */ public int getTime() { return (time + HOUR_ZERO) % TICKS_PER_DAY; } @Override public String toString() { return toString(time); } public static String toString(final int ticks) { assert 0 <= ticks && ticks < TICKS_PER_DAY; final int t = (ticks + HOUR_ZERO) % TICKS_PER_DAY; int hours = t / TICKS_PER_HOUR; int minutes = (int) (Math.round((t % TICKS_PER_HOUR) / TICKS_PER_MINUTE)); if (minutes >= 60) { hours = (hours + 1) % 24; minutes -= 60; } return "" + hours + ":" + (minutes < 10 ? "0" : "") + minutes; } private final static Message m_error_24_hours = new Message("time.errors.24 hours"); private final static Message m_error_12_hours = new Message("time.errors.12 hours"); private final static Message m_error_60_minutes = new Message("time.errors.60 minutes"); /** * @param s The trim()med string to parse * @return The parsed time of null if the input was invalid */ @SuppressWarnings("null") @Nullable public final static Time parse(final String s) { // if (s.matches("\\d+")) { // return new Time(Integer.parseInt(s)); // } else if (s.matches("\\d?\\d:\\d\\d")) { int hours = Utils.parseInt(s.split(":")[0]); if (hours == 24) { // allows to write 24:00 - 24:59 instead of 0:00-0:59 hours = 0; } else if (hours > 24) { Skript.error("" + m_error_24_hours); return null; } final int minutes = Utils.parseInt(s.split(":")[1]); if (minutes >= 60) { Skript.error("" + m_error_60_minutes); return null; } return new Time((int) Math.round(hours * TICKS_PER_HOUR - HOUR_ZERO + minutes * TICKS_PER_MINUTE)); } else { final Matcher m = Pattern.compile("(\\d?\\d)(:(\\d\\d))? ?(am|pm)", Pattern.CASE_INSENSITIVE).matcher(s); if (m.matches()) { int hours = Utils.parseInt(m.group(1)); if (hours == 12) { hours = 0; } else if (hours > 12) { Skript.error("" + m_error_12_hours); return null; } int minutes = 0; if (m.group(3) != null) minutes = Utils.parseInt(m.group(3)); if (minutes >= 60) { Skript.error("" + m_error_60_minutes); return null; } if (m.group(4).equalsIgnoreCase("pm")) hours += 12; return new Time((int) Math.round(hours * TICKS_PER_HOUR - HOUR_ZERO + minutes * TICKS_PER_MINUTE)); } } return null; } @Override public int hashCode() { return time; } @Override public boolean equals(final @Nullable Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Time)) return false; final Time other = (Time) obj; return time == other.time; } }