List of usage examples for java.util Calendar ZONE_OFFSET
int ZONE_OFFSET
To view the source code for java.util Calendar ZONE_OFFSET.
Click Source Link
get
and set
indicating the raw offset from GMT in milliseconds. From source file:gov.noaa.pfel.coastwatch.Projects.java
/** * Processes one CalCOFI2012 tsv file into a .nc file. * // w w w .j a va 2s . c o m * <p>The var sequence of latitude, latitudeMinutes, latitudeLocation * will be converted to 1 latitude column (decimal degrees). * Similar with longitude. * * <p>If units are yyMM, var will be converted to yyyyMM and units="". * * <p>If units are yyMMdd, var will be converted to yyyyMMdd, then * to "seconds since 1970-01-01T00:00:00Z" (assuming Pacific time zone) * and sets attribute: time_precision=1970-01-01. * * <p>If units of variable after yyMMdd are HHmm, the date and time will * be combined into one "seconds since 1970-01-01T00:00:00Z" variable. * * <p>If variableName="timeZone", this checks to see if arriveDate value * timeZone offset is as expected. * * @param dir * @param tableName e.g., CC_TOWS * @param info with 4 strings (name, type, units, long_name) for each variable * @param towTypesDescription will be added as description=[towTypesDescrption] * when variableName=towTypeCode. * @return the table, as saved in the .nc file. */ public static Table processOneCalcofi2012(String dir, String tableName, String info[], String towTypesDescription) throws Exception { String rowName = "row"; int cutoffYear = 20; // fourDigitYear += twoDigitYear < cutoffYear? 2000 : 1900; /* make tsv into ERDDAP-style .json table //{ // "table": { // "columnNames": ["longitude", "latitude", "time", "sea_surface_temperature"], // "columnTypes": ["float", "float", "String", "float"], // "columnUnits": ["degrees_east", "degrees_north", "UTC", "degree_C"], // "rows": [ // [180.099, 0.032, "2007-10-04T12:00:00Z", 27.66], // [180.099, 0.032, null, null], // [189.971, -7.98, "2007-10-04T12:00:00Z", 29.08] // ] //} */ String inFile = dir + tableName + ".txt"; String2.log("\n* processOneCalcofi2012 " + inFile); StringArray names = new StringArray(); StringArray types = new StringArray(); StringArray units = new StringArray(); StringArray lNames = new StringArray(); Test.ensureEqual(info.length % 4, 0, "info.length=" + info.length); int nVars = info.length / 4; int n = 0; for (int v = 0; v < nVars; v++) { names.add(info[n++]); types.add(info[n++]); units.add(info[n++]); lNames.add(info[n++]); } String fromFile[] = String2.readFromFile(inFile); if (fromFile[0].length() > 0) throw new RuntimeException(fromFile[0]); String lines = String2.replaceAll(fromFile[1], "\t", ","); lines = String2.replaceAll(lines, "\n", "],\n["); lines = "{\n" + " \"table\": {\n" + " \"columnNames\": [" + names.toJsonCsvString() + "],\n" + " \"columnTypes\": [" + types.toJsonCsvString() + "],\n" + " \"columnUnits\": [" + units.toJsonCsvString() + "],\n" + " \"rows\": [\n" + "[" + lines.substring(0, lines.length() - 3) + "\n" + "]\n" + "}\n"; String2.log(lines.substring(0, Math.min(lines.length(), 1500))); Table table = new Table(); table.readJson(inFile, lines); String2.log("Before adjustments:\n" + String2.annotatedString(table.dataToString(5))); int nRows = table.nRows(); int nErrors = 0; //things where nColumns won't change for (int v = 0; v < table.nColumns(); v++) { PrimitiveArray pa = table.getColumn(v); String vName = table.getColumnName(v); Attributes atts = table.columnAttributes(v); //longNames atts.add("long_name", lNames.get(v)); //relies on original var lists //timeZone nErrors = 0; if ("timeZone".equals(vName)) { PrimitiveArray arrivePA = table.getColumn("arriveDate"); //still yyMMdd GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles")); Calendar2.clearSmallerFields(gc, Calendar2.DATE); for (int row = 0; row < nRows; row++) { String val = arrivePA.getString(row); if (val.matches("[0-9]{6}")) { int year = String2.parseInt(val.substring(0, 2)); gc.set(Calendar2.YEAR, year < cutoffYear ? 2000 : 1900); gc.set(Calendar2.MONTH, String2.parseInt(val.substring(2, 4)) - 1); //0.. gc.set(Calendar2.DATE, String2.parseInt(val.substring(4, 6))); int fileHas = pa.getInt(row); int calculated = -gc.get(Calendar.ZONE_OFFSET) / (60 * 60 * 1000) + //in hours -gc.get(Calendar.DST_OFFSET) / (60 * 60 * 1000); //in hours if (fileHas != calculated) { nErrors++; if (nErrors <= 5) String2.log("ERROR: col=" + vName + " row=" + row + " timeZone=" + fileHas + " != calculated(" + val + ")=" + calculated); } } } if (nErrors > 0) String2.pressEnterToContinue("Bob: check US daylight savings time rules. On/near these dates?\n" + "https://en.wikipedia.org/wiki/History_of_time_in_the_United_States\n" + "nErrors=" + nErrors); } } //things where nColumns may change for (int v = 0; v < table.nColumns(); v++) { PrimitiveArray pa = table.getColumn(v); String vName = table.getColumnName(v); Attributes atts = table.columnAttributes(v); String vUnits = atts.getString("units"); Attributes nextAtts = v < table.nColumns() - 1 ? table.columnAttributes(v + 1) : new Attributes(); //towTypeCode if ("towTypeCode".equals(vName)) atts.add("description", towTypesDescription); //latitude nErrors = 0; if ("latitude".equals(vName) && "latitudeMinutes".equals(table.getColumnName(v + 1)) && "latitudeLocation".equals(table.getColumnName(v + 2))) { FloatArray fa = new FloatArray(nRows, false); //float avoids, e.g., xx.33333333333333 PrimitiveArray pa1 = table.getColumn(v + 1); PrimitiveArray pa2 = table.getColumn(v + 2); for (int row = 0; row < nRows; row++) { String loc = pa2.getString(row); String combo = pa.getString(row) + " " + pa1.getString(row) + " " + loc; float f = //will be NaN if trouble (pa.getFloat(row) + (pa1.getFloat(row) / 60)) * (loc.equals("N") ? 1 : loc.equals("S") ? -1 : Float.NaN); fa.atInsert(row, f); if (combo.length() > 2 && //2 spaces (f < -90 || f > 90 || Float.isNaN(f))) { nErrors++; if (nErrors <= 5) String2.log("ERROR: col=" + vName + " row=" + row + " lat=" + combo + " -> " + f); } } table.setColumn(v, fa); table.removeColumn(v + 2); table.removeColumn(v + 1); } if (nErrors > 0) String2.pressEnterToContinue("nErrors=" + nErrors); //longitude nErrors = 0; if ("longitude".equals(vName) && "longitudeMinutes".equals(table.getColumnName(v + 1)) && "longitudeLocation".equals(table.getColumnName(v + 2))) { FloatArray fa = new FloatArray(nRows, false); //float avoids, e.g., xx.33333333333333 PrimitiveArray pa1 = table.getColumn(v + 1); PrimitiveArray pa2 = table.getColumn(v + 2); for (int row = 0; row < nRows; row++) { String loc = pa2.getString(row); String combo = pa.getString(row) + " " + pa1.getString(row) + " " + loc; float f = //will be NaN if trouble (pa.getFloat(row) + (pa1.getFloat(row) / 60)) * (loc.equals("E") ? 1 : loc.equals("W") ? -1 : Float.NaN); fa.atInsert(row, f); if (combo.length() > 2 && //2 spaces (f < -180 || f > 180 || Float.isNaN(f))) { nErrors++; if (nErrors <= 5) String2.log("ERROR: col=" + vName + " row=" + row + " lat=" + combo + " -> " + f); } } table.setColumn(v, fa); table.removeColumn(v + 2); table.removeColumn(v + 1); } if (nErrors > 0) String2.pressEnterToContinue("nErrors=" + nErrors); //yyMM add century to cruiseYYMM nErrors = 0; if ("yyMM".equals(vUnits)) { for (int row = 0; row < nRows; row++) { String val = pa.getString(row); if (val.matches("[0-9]{4}")) { int year = String2.parseInt(val.substring(0, 2)); pa.setString(row, (year < cutoffYear ? "20" : "19") + val); } else { if (val.length() != 0) { nErrors++; if (nErrors <= 5) String2.log("ERROR: col=" + vName + " row=" + row + " yyMM=" + val); } pa.setString(row, ""); //set to MV } } atts.set("units", ""); //leave it as a String identifier } if (nErrors > 0) String2.pressEnterToContinue("nErrors=" + nErrors); //yyMMdd nErrors = 0; if ("yyMMdd".equals(vUnits)) { String nextUnits = nextAtts.getString("units"); boolean nextHasMinutes = "HHmm".equals(nextUnits); if (nextHasMinutes) String2.log("combining yyMMdd and next column (HHmm)"); String nextVName = nextHasMinutes ? table.getColumnName(v + 1) : ""; DoubleArray datePA = new DoubleArray(nRows, false); PrimitiveArray minutesPA = nextHasMinutes ? table.getColumn(v + 1) : (PrimitiveArray) null; //??!! Use Zulu or local, or time_zone data (in one table only)? GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles")); Calendar2.clearSmallerFields(gc, Calendar2.DATE); for (int row = 0; row < nRows; row++) { String val = pa.getString(row); if (val.matches("[0-9]{6}")) { int year = String2.parseInt(val.substring(0, 2)); gc.set(Calendar2.YEAR, year < cutoffYear ? 2000 : 1900); gc.set(Calendar2.MONTH, String2.parseInt(val.substring(2, 4)) - 1); //0.. gc.set(Calendar2.DATE, String2.parseInt(val.substring(4, 6))); if (nextHasMinutes) { Calendar2.clearSmallerFields(gc, Calendar2.DATE); int HHmm = minutesPA.getInt(row); if (HHmm < 0 || HHmm > 2359) { nErrors++; if (nErrors <= 5) String2.log("ERROR: col=" + nextVName + " row=" + row + " HHmm=" + minutesPA.getString(row)); } else { gc.set(Calendar2.HOUR_OF_DAY, HHmm / 100); gc.set(Calendar2.MINUTE, HHmm % 100); } } datePA.add(Calendar2.gcToEpochSeconds(gc)); } else { if (val.length() != 0) { nErrors++; if (nErrors <= 5) String2.log("ERROR: col=" + vName + " row=" + row + " yyMMdd=" + val); } datePA.add(Double.NaN); } } table.setColumn(v, datePA); atts.set("units", Calendar2.SECONDS_SINCE_1970); atts.set("time_precision", //AKA EDV.TIME_PRECISION nextHasMinutes ? "1970-01-01T00:00" : "1970-01-01"); if (nextHasMinutes) table.removeColumn(v + 1); } if (nErrors > 0) String2.pressEnterToContinue("nErrors=" + nErrors); } //save as .nc String2.log("After adjustments:\n" + String2.annotatedString(table.dataToString(5))); table.saveAsFlatNc(dir + tableName + ".nc", rowName, false); return table; }