/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2014, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotools.imageio.netcdf.utilities; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashSet; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.TimeUnit; /** * @author User * */ public class NetCDFTimeUtilities { public static final int JGREG = 15 + 31 * (10 + 12 * 1582); public final static TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("GMT"); public final static Set<String> MONTH_SET = new HashSet<String>(); public final static Set<String> DAY_SET = new HashSet<String>(); public final static Set<String> HOUR_SET = new HashSet<String>(); public final static Set<String> MINUTE_SET = new HashSet<String>(); public final static Set<String> SECOND_SET = new HashSet<String>(); static { MONTH_SET.add("month"); MONTH_SET.add("months"); DAY_SET.add("d"); DAY_SET.add("day"); DAY_SET.add("days"); HOUR_SET.add("h"); HOUR_SET.add("hr"); HOUR_SET.add("hrs"); HOUR_SET.add("hour"); HOUR_SET.add("hours"); MINUTE_SET.add("min"); MINUTE_SET.add("mins"); MINUTE_SET.add("minute"); MINUTE_SET.add("minutes"); SECOND_SET.add("s"); SECOND_SET.add("sec"); SECOND_SET.add("secs"); SECOND_SET.add("second"); SECOND_SET.add("seconds"); } /** * */ private NetCDFTimeUtilities() { } /** * @param origin */ public static String checkDateDigits(String origin) { String digitsCheckedOrigin = ""; if (origin.indexOf("-") > 0) { String tmp = (origin.indexOf(" ") > 0 ? origin.substring(0, origin.indexOf(" ")) : origin); String[] originDateParts = tmp.split("-"); for (int l = 0; l < originDateParts.length; l++) { String datePart = originDateParts[l]; while (datePart.length() % 2 != 0) { datePart = "0" + datePart; } digitsCheckedOrigin += datePart; digitsCheckedOrigin += (l < (originDateParts.length - 1) ? "-" : ""); } } if (origin.indexOf(":") > 0) { digitsCheckedOrigin += " "; String tmp = (origin.indexOf(" ") > 0 ? origin.substring(origin.indexOf(" ") + 1) : origin); String[] originDateParts = tmp.split(":"); for (int l = 0; l < originDateParts.length; l++) { String datePart = originDateParts[l]; while (datePart.length() % 2 != 0) { datePart = "0" + datePart; } digitsCheckedOrigin += datePart; digitsCheckedOrigin += (l < (originDateParts.length - 1) ? ":" : ""); } } if (digitsCheckedOrigin.length() > 0) return digitsCheckedOrigin; return origin; } public static GregorianCalendar fromJulian(double injulian) { int jalpha, ja, jb, jc, jd, je, year, month, day; // double julian = injulian + HALFSECOND / 86400.0; ja = (int) injulian; if (ja >= JGREG) { jalpha = (int) (((ja - 1867216) - 0.25) / 36524.25); ja = ja + 1 + jalpha - jalpha / 4; } jb = ja + 1524; jc = (int) (6680.0 + ((jb - 2439870) - 122.1) / 365.25); jd = 365 * jc + jc / 4; je = (int) ((jb - jd) / 30.6001); day = jb - jd - (int) (30.6001 * je); month = je - 1; if (month > 12) month = month - 12; year = jc - 4715; if (month > 2) year--; if (year <= 0) year--; // Calendar Months are 0 based return new GregorianCalendar(year, month - 1, day); } /** * */ public static int getTimeSubUnitsValue(String units, Double vd) { if (units == null || units.isEmpty()) { return 0; } String unit = units.toLowerCase(); if (DAY_SET.contains(unit)) { int subUnit = getTimeUnits(units, vd); if (subUnit == Calendar.HOUR) { double hours = vd * 24; return (int) hours; } else if (subUnit == Calendar.MINUTE) { double minutes = vd * 24 * 60; return (int) minutes; } else if (subUnit == Calendar.SECOND) { double seconds = vd * 24 * 60 * 60; return (int) seconds; } else if (subUnit == Calendar.MILLISECOND) { double milliseconds = vd * 24 * 60 * 60 * 1000; return (int) milliseconds; } } else if (HOUR_SET.contains(unit)) { int subUnit = getTimeUnits(units, vd); if (subUnit == Calendar.MINUTE) { double minutes = vd * 60; return (int) minutes; } else if (subUnit == Calendar.SECOND) { double seconds = vd * 60 * 60; return (int) seconds; } else if (subUnit == Calendar.MILLISECOND) { double milliseconds = vd * 60 * 60 * 1000; return (int) milliseconds; } } else if (MINUTE_SET.contains(unit)) { int subUnit = getTimeUnits(units, vd); if (subUnit == Calendar.SECOND) { double seconds = vd * 60; return (int) seconds; } else if (subUnit == Calendar.MILLISECOND) { double milliseconds = vd * 60 * 1000; return (int) milliseconds; } } else if (SECOND_SET.contains(unit)) { int subUnit = getTimeUnits(units, vd); if (subUnit == Calendar.MILLISECOND) { double milliseconds = vd * 1000; return (int) milliseconds; } } return 0; } /** * Converts NetCDF time units into opportune Calendar ones. * * @param units {@link String} * @param d * @return int */ public static int getTimeUnits(String units, Double vd) { if (units == null || units.isEmpty()) { return -1; } String unit = units.toLowerCase(); if (MONTH_SET.contains(unit)) { if (vd == null || vd == 0.0) // if no day, it is the first day return Calendar.MONTH; else { // TODO: FIXME } } else if (DAY_SET.contains(unit)) { if (vd == null || vd == 0.0) return Calendar.DATE; else { double hours = vd * 24; if (hours - Math.floor(hours) == 0.0) return Calendar.HOUR; double minutes = vd * 24 * 60; if (minutes - Math.floor(minutes) == 0.0) return Calendar.MINUTE; double seconds = vd * 24 * 60 * 60; if (seconds - Math.floor(seconds) == 0.0) return Calendar.SECOND; return Calendar.MILLISECOND; } } else if (HOUR_SET.contains(unit)) { if (vd == null || vd == 0.0) return Calendar.HOUR; else { double minutes = vd * 60; if (minutes - Math.floor(minutes) == 0.0) return Calendar.MINUTE; double seconds = vd * 60 * 60; if (seconds - Math.floor(seconds) == 0.0) return Calendar.SECOND; return Calendar.MILLISECOND; } } else if (MINUTE_SET.contains(unit)) { if (vd == null || vd == 0.0) return Calendar.MINUTE; else { double seconds = vd * 60; if (seconds - Math.floor(seconds) == 0.0) return Calendar.SECOND; return Calendar.MILLISECOND; } } else if (SECOND_SET.contains(unit)) { if (vd == null || vd == 0.0) return Calendar.SECOND; else { return Calendar.MILLISECOND; } } return -1; } /** * * @param value * @return */ public static String trimFractionalPart(String value) { value = value.trim(); for (int i = value.length(); --i >= 0;) { switch (value.charAt(i)) { case '0': continue; case '.': return value.substring(0, i); default: return value; } } return value; } /** * Add a quantity of time units to a Calendar * * @param cal Calendar to add to * @param unit Calendar unit to add * @param val Quantity of unit to add */ public static void addTimeUnit(Calendar cal, int unit, int val) { addTimeUnit(cal, unit, (long) val); } /** * Add a quantity of time units to a Calendar * * @param cal Calendar to add to * @param unit Calendar unit to add * @param val Quantity of TimeUnit to add */ public static void addTimeUnit(Calendar cal, int unit, long val) { if (unit == Calendar.DATE) { cal.setTimeInMillis(cal.getTimeInMillis() + TimeUnit.DAYS.toMillis(val)); } else if (unit == Calendar.HOUR) { cal.setTimeInMillis(cal.getTimeInMillis() + TimeUnit.HOURS.toMillis(val)); } else if (unit == Calendar.MINUTE) { cal.setTimeInMillis(cal.getTimeInMillis() + TimeUnit.MINUTES.toMillis(val)); } else if (unit == Calendar.SECOND) { cal.setTimeInMillis(cal.getTimeInMillis() + TimeUnit.SECONDS.toMillis(val)); } else if (unit == Calendar.MILLISECOND) { cal.setTimeInMillis(cal.getTimeInMillis() + val); } else { int intVal = (int) val; if (intVal != val) { throw new IllegalArgumentException("Can't convert " + val + " to an int without losing data"); } cal.add(unit, intVal); } } }