Example usage for java.util Calendar ZONE_OFFSET

List of usage examples for java.util Calendar ZONE_OFFSET

Introduction

In this page you can find the example usage for java.util Calendar ZONE_OFFSET.

Prototype

int ZONE_OFFSET

To view the source code for java.util Calendar ZONE_OFFSET.

Click Source Link

Document

Field number for get and set indicating the raw offset from GMT in milliseconds.

Usage

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;
}