Example usage for org.joda.time DateTimeZone UTC

List of usage examples for org.joda.time DateTimeZone UTC

Introduction

In this page you can find the example usage for org.joda.time DateTimeZone UTC.

Prototype

DateTimeZone UTC

To view the source code for org.joda.time DateTimeZone UTC.

Click Source Link

Document

The time zone for Universal Coordinated Time

Usage

From source file:VMwareInventory.java

/**
 * readings//from   w w  w  . ja v  a 2s  .c o m
 *
 * gather properties for VMs in requested List and readings.  Populates this.vmMap and this.hostMap
 *
 * @param  vms List<VirtualMachine> 
 * @param  startTime Calendar
 * @param  endTime Calendar
 */
public void readings(List<VirtualMachine> vms, Calendar startTime, Calendar endTime) throws Exception {
    logger.fine(
            "Entering VMwareInventory.readings(List<VirtualMachine> vms, Calendar startTime, Calendar endTime)");
    String[] counterNames = { "cpu.usage.average", "cpu.usagemhz.average", "mem.consumed.average",
            "virtualDisk.read.average", "virtualDisk.write.average", "net.received.average",
            "net.transmitted.average" };
    gatherCounters();
    PerfMetricId cpu_usage = new PerfMetricId();
    cpu_usage.setCounterId(this.counterMap.get("cpu.usage.average"));
    cpu_usage.setInstance("");

    PerfMetricId cpu_usagemhz = new PerfMetricId();
    cpu_usagemhz.setCounterId(this.counterMap.get("cpu.usagemhz.average"));
    cpu_usagemhz.setInstance("");

    PerfMetricId mem = new PerfMetricId();
    mem.setCounterId(this.counterMap.get("mem.consumed.average"));
    mem.setInstance("");

    PerfMetricId vdisk_read = new PerfMetricId();
    vdisk_read.setCounterId(this.counterMap.get("virtualDisk.read.average"));
    vdisk_read.setInstance("*");

    PerfMetricId vdisk_write = new PerfMetricId();
    vdisk_write.setCounterId(this.counterMap.get("virtualDisk.write.average"));
    vdisk_write.setInstance("*");

    PerfMetricId net_recv = new PerfMetricId();
    net_recv.setCounterId(this.counterMap.get("net.received.average"));
    net_recv.setInstance("*");

    PerfMetricId net_trans = new PerfMetricId();
    net_trans.setCounterId(this.counterMap.get("net.transmitted.average"));
    net_trans.setInstance("*");

    List<PerfQuerySpec> qSpecList = new ArrayList<PerfQuerySpec>();
    Iterator it = vms.iterator();
    while (it.hasNext()) {
        PerfQuerySpec qSpec = new PerfQuerySpec();
        VirtualMachine vm = (VirtualMachine) it.next();
        qSpec.setEntity(vm.getMOR());
        qSpec.setFormat("normal");
        qSpec.setIntervalId(300);
        qSpec.setMetricId(new PerfMetricId[] { cpu_usage, cpu_usagemhz, mem, vdisk_read, vdisk_write,
                vdisk_write, net_trans, net_recv });
        qSpec.setStartTime(startTime);
        qSpec.setEndTime(endTime);
        qSpecList.add(qSpec);
    }

    PerformanceManager pm = getPerformanceManager();
    PerfQuerySpec[] pqsArray = qSpecList.toArray(new PerfQuerySpec[qSpecList.size()]);
    logger.info("Start PerformanceManager.queryPerf");
    PerfEntityMetricBase[] pembs = pm.queryPerf(pqsArray);
    logger.info("Finished PerformanceManager.queryPerf");
    logger.info("Start gathering of valid timestamps");
    DateTimeFormatter fmt = ISODateTimeFormat.dateTimeNoMillis();
    String timestamp = fmt.withZone(DateTimeZone.UTC).print(endTime.getTimeInMillis());
    this.tsSet.add(timestamp);
    for (int i = 0; pembs != null && i < pembs.length; i++) {
        if (pembs[i] instanceof PerfEntityMetric) {
            parseValidTimestamps((PerfEntityMetric) pembs[i]);
        }

    }
    // Prepopulate with all timestamps
    String[] ts = this.tsSet.toArray(new String[0]);
    for (String moref : this.vmMap.keySet()) {
        HashMap<String, HashMap<String, Long>> metrics = new HashMap<String, HashMap<String, Long>>();
        for (int i = 0; ts != null && i < ts.length; i++) {
            metrics.put(ts[i], new HashMap<String, Long>());
        }
        this.vmMap.get(moref).put("stats", metrics);
    }
    logger.info("Finished gathering of valid timestamps");
    logger.info("Start parsing metrics");
    for (int i = 0; pembs != null && i < pembs.length; i++) {
        //DEBUG - printPerfMetric(pembs[i]);
        if (pembs[i] instanceof PerfEntityMetric) {
            String vm_mor = pembs[i].getEntity().get_value();
            HashMap<String, HashMap<String, Long>> metrics = parsePerfMetricForVM(vm_mor,
                    (PerfEntityMetric) pembs[i]);
            this.vmMap.get(vm_mor).put("stats", metrics);
            // DEBUG - printMachineReading(vm_mor,metrics);
        }
    }
    logger.info("Finished parsing metrics");
    logger.fine("Exiting VMwareInventory.readings(String startIso8601, String endIso8601)");
}

From source file:VMwareInventory.java

private void parseValidTimestamps(PerfEntityMetric pem) {
    logger.fine("Entering VMwareInventory.readings(String startIso8601, String endIso8601)");
    PerfSampleInfo[] infos = pem.getSampleInfo();
    for (int i = 0; infos != null && i < infos.length; i++) {
        DateTimeFormatter fmt = ISODateTimeFormat.dateTimeNoMillis();
        String timestamp = fmt.withZone(DateTimeZone.UTC).print(infos[i].getTimestamp().getTimeInMillis());
        this.tsSet.add(timestamp);
        logger.finer("parseValidTimestmaps() found " + timestamp);
    }/*  w  w w. j  ava2s  .  co  m*/
    logger.fine(
            "Exiting VMwareInventory.readings(List<VirtualMachine> vms, Calendar startTime, Calendar endTime)");

}

From source file:VMwareInventory.java

private HashMap<String, HashMap<String, Long>> parsePerfMetricForVM(String vm_mor, PerfEntityMetric pem) {
    logger.fine("Entering VMwareInventory.parsePerfMetricForVM(String vm_mor, PerfEntityMetric pem)");
    PerfMetricSeries[] vals = pem.getValue();
    PerfSampleInfo[] infos = pem.getSampleInfo();
    HashMap<String, Object> vm_hash = this.vmMap.get(vm_mor);
    @SuppressWarnings("unchecked")
    HashMap<String, HashMap<String, Long>> metrics = (HashMap<String, HashMap<String, Long>>) vm_hash
            .get("stats");
    // Prepopulate with all timestamps
    String[] ts = this.tsSet.toArray(new String[0]);
    for (int i = 0; ts != null && i < ts.length; i++) {
        metrics.put(ts[i], new HashMap<String, Long>());
    }/*  w w w.  j a v a  2s.  c o m*/
    // Fill in metrics gathered
    for (int i = 0; infos != null && i < infos.length; i++) {
        DateTimeFormatter fmt = ISODateTimeFormat.dateTimeNoMillis();
        String timestamp = fmt.withZone(DateTimeZone.UTC).print(infos[i].getTimestamp().getTimeInMillis());
        for (int j = 0; vals != null && j < vals.length; ++j) {
            String counterName = this.counterIdMap.get(vals[j].getId().getCounterId());
            String instanceName = vals[j].getId().getInstance();
            String metricName = counterName;
            if (instanceName.length() > 0) {
                metricName = counterName + "." + instanceName;
            }
            if (vals[j] instanceof PerfMetricIntSeries) {
                PerfMetricIntSeries val = (PerfMetricIntSeries) vals[j];
                long[] longs = val.getValue();
                long value = longs[i];
                metrics.get(timestamp).put(metricName, value);
                logger.finer("parsePerfMetricForVM adding " + timestamp + " " + metricName + " " + value);
            }
        }
    }
    logger.fine("Exiting VMwareInventory.parsePerfMetricForVM(String vm_mor, PerfEntityMetric pem)");
    return (metrics);
}

From source file:$.ServiceApplication.java

License:Apache License

public static void main(String[] args) throws Exception {
        DateTimeZone.setDefault(DateTimeZone.UTC);

        ServiceApplication serviceApplication = new ServiceApplication(new GuiceBundleProvider());

        try {//www .ja v a2  s  .  co m
            serviceApplication.run(args);
        } catch (Throwable ex) {
            ex.printStackTrace();

            System.exit(1);
        }
    }

From source file:aaf.vhr.idp.http.VhrRemoteUserAuthServlet.java

License:Open Source License

/** {@inheritDoc} */
@Override/*from w ww .  j  av a2  s  . c  o m*/
protected void service(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse)
        throws ServletException, IOException {

    try {
        // key to ExternalAuthentication session
        String key = null;
        boolean isVhrReturn = false;
        boolean isForceAuthn = false;
        DateTime authnStart = null; // when this authentication started at the IdP
        // array to use as return parameter when calling VhrSessionValidator
        DateTime authnInstantArr[] = new DateTime[1];

        if (httpRequest.getParameter(REDIRECT_REQ_PARAM_NAME) != null) {
            // we have come back from the VHR
            isVhrReturn = true;
            key = httpRequest.getParameter(REDIRECT_REQ_PARAM_NAME);
            HttpSession hs = httpRequest.getSession();

            if (hs != null && hs.getAttribute(AUTHN_INIT_INSTANT_ATTR_NAME + key) != null) {
                authnStart = (DateTime) hs.getAttribute(AUTHN_INIT_INSTANT_ATTR_NAME + key);
                // remove the attribute from the session so that we do not attempt to reuse it...
                hs.removeAttribute(AUTHN_INIT_INSTANT_ATTR_NAME);
            }
            ;

            if (hs != null && hs.getAttribute(IS_FORCE_AUTHN_ATTR_NAME + key) != null) {
                isForceAuthn = ((Boolean) hs.getAttribute(IS_FORCE_AUTHN_ATTR_NAME + key)).booleanValue();
                // remove the attribute from the session so that we do not attempt to reuse it...
                hs.removeAttribute(AUTHN_INIT_INSTANT_ATTR_NAME);
            }
            ;

        } else {
            // starting a new SSO request
            key = ExternalAuthentication.startExternalAuthentication(httpRequest);

            // check if forceAuthn is set
            Object forceAuthnAttr = httpRequest.getAttribute(ExternalAuthentication.FORCE_AUTHN_PARAM);
            if (forceAuthnAttr != null && forceAuthnAttr instanceof java.lang.Boolean) {
                log.debug("Loading foceAuthn value");
                isForceAuthn = ((Boolean) forceAuthnAttr).booleanValue();
            }

            // check if we can see when authentication was initiated
            final AuthenticationContext authCtx = ExternalAuthentication
                    .getProfileRequestContext(key, httpRequest)
                    .getSubcontext(AuthenticationContext.class, false);
            if (authCtx != null) {
                log.debug("Authentication initiation is {}", authCtx.getInitiationInstant());
                authnStart = new DateTime(authCtx.getInitiationInstant(), DateTimeZone.UTC);
                log.debug("AuthnStart is {}", authnStart);
            }
            ;

        }
        ;
        log.debug("forceAuthn is {}, authnStart is {}", isForceAuthn, authnStart);

        if (key == null) {
            log.error("No ExternalAuthentication sesssion key found");
            throw new ServletException("No ExternalAuthentication sesssion key found");
        }
        ;
        // we now have a key - either:
        // * we started new authentication
        // * or we have returned from VHR and loaded the key from the HttpSession

        String username = null;

        // We may have a cookie - either as part of return or from previous session
        // Attempt to locate VHR SessionID
        String vhrSessionID = null;
        Cookie[] cookies = httpRequest.getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(SSO_COOKIE_NAME)) {
                vhrSessionID = cookie.getValue();
                break;
            }
        }

        if (vhrSessionID != null) {
            log.info("Found vhrSessionID from {}. Establishing validity.", httpRequest.getRemoteHost());
            username = vhrSessionValidator.validateSession(vhrSessionID, (isForceAuthn ? authnStart : null),
                    authnInstantArr);
        }
        ;

        // If we do not have a username yet (no Vhr session cookie or did not validate),
        // we redirect to VHR - but only if we are not returning from the VHR
        // Reason: (i) we do not want to loop and (ii) we do not have the full context otherwise initialized by
        // ExternalAuthentication.startExternalAuthentication()
        if (username == null && !isVhrReturn) {

            URLCodec codec = new URLCodec();
            String relyingParty = (String) httpRequest.getAttribute("relyingParty");
            String serviceName = "";

            log.info("No vhrSessionID found from {}. Directing to VHR authentication process.",
                    httpRequest.getRemoteHost());
            log.debug("Relying party which initiated the SSO request was: {}", relyingParty);

            // try getting a RelyingPartyUIContext
            // we should pass on the request for consent revocation
            final ProfileRequestContext prc = ExternalAuthentication.getProfileRequestContext(key, httpRequest);
            final RelyingPartyUIContext rpuiCtx = prc.getSubcontext(AuthenticationContext.class, true)
                    .getSubcontext(RelyingPartyUIContext.class, false);
            if (rpuiCtx != null) {
                serviceName = rpuiCtx.getServiceName();
                log.debug("RelyingPartyUIContext received, ServiceName is {}", serviceName);
            }
            ;

            // save session *key*
            HttpSession hs = httpRequest.getSession(true);
            hs.setAttribute(IS_FORCE_AUTHN_ATTR_NAME + key, new Boolean(isForceAuthn));
            hs.setAttribute(AUTHN_INIT_INSTANT_ATTR_NAME + key, authnStart);

            try {
                httpResponse.sendRedirect(String.format(vhrLoginEndpoint,
                        codec.encode(httpRequest.getRequestURL().toString() + "?" + REDIRECT_REQ_PARAM_NAME
                                + "=" + codec.encode(key)),
                        codec.encode(relyingParty), codec.encode(serviceName)));
            } catch (EncoderException e) {
                log.error("Could not encode VHR redirect params");
                throw new IOException(e);
            }
            return; // we issued a redirect - return now
        }
        ;

        if (username == null) {
            log.warn("VirtualHome authentication failed: no username received");
            httpRequest.setAttribute(ExternalAuthentication.AUTHENTICATION_ERROR_KEY,
                    "VirtualHome authentication failed: no username received");
            ExternalAuthentication.finishExternalAuthentication(key, httpRequest, httpResponse);
            return;
        }

        // check if consent revocation was requested
        String consentRevocationParam = httpRequest.getParameter(consentRevocationParamName);
        if (consentRevocationParam != null) {
            // we should pass on the request for consent revocation
            final ProfileRequestContext prc = ExternalAuthentication.getProfileRequestContext(key, httpRequest);
            final ConsentManagementContext consentCtx = prc.getSubcontext(ConsentManagementContext.class, true);
            log.debug("Consent revocation request received, setting revokeConsent in consentCtx");
            consentCtx.setRevokeConsent(consentRevocationParam.equalsIgnoreCase("true"));
        }
        ;

        // Set authnInstant to timestamp returned by VHR
        if (authnInstantArr[0] != null) {
            log.debug("Response from VHR includes authenticationInstant time {}, passing this back to IdP",
                    authnInstantArr[0]);
            httpRequest.setAttribute(ExternalAuthentication.AUTHENTICATION_INSTANT_KEY, authnInstantArr[0]);
        }
        ;

        httpRequest.setAttribute(ExternalAuthentication.PRINCIPAL_NAME_KEY, username);

        ExternalAuthentication.finishExternalAuthentication(key, httpRequest, httpResponse);

    } catch (final ExternalAuthenticationException e) {
        throw new ServletException("Error processing external authentication request", e);
    }
}

From source file:app.decoder.data.wrap.WrapEntry.java

License:BSD License

public TimeValue getTradeDate() {
    if (MessageRules.hasTradeDate(getMessage(), entry)) {
        final int days = MessageRules.getTradeDate(getMessage(), entry);
        final MutableDateTime date = new MutableDateTime(0, DateTimeZone.UTC);
        date.addDays(days);/*from w  w  w . j ava  2  s  . co  m*/
        return ValueBuilder.newTime(date.getMillis());
    } else {
        return ValueConst.NULL_TIME;
    }
}

From source file:app.rappla.calendar.Date.java

License:Open Source License

/**
 * Constructor/*from  ww  w  . j a  v a 2s .c o  m*/
 * 
 * @param icalStr
 *            One or more lines of iCalendar that specifies a date
 * @param parseMode
 *            PARSE_STRICT or PARSE_LOOSE
 */
public Date(String icalStr) throws ParseException, BogusDataException {
    super(icalStr);

    year = month = day = 0;
    hour = minute = second = 0;

    for (int i = 0; i < attributeList.size(); i++) {
        Attribute a = attributeAt(i);
        String aname = a.name.toUpperCase(Locale.ENGLISH);
        String aval = a.value.toUpperCase(Locale.ENGLISH);
        // TODO: not sure if any attributes are allowed here...
        // Look for VALUE=DATE or VALUE=DATE-TIME
        // DATE means untimed for the event
        if (aname.equals("VALUE")) {
            if (aval.equals("DATE")) {
                dateOnly = true;
            } else if (aval.equals("DATE-TIME")) {
                dateOnly = false;
            }
        } else if (aname.equals("TZID")) {
            tzid = a.value;
        } else {
            // TODO: anything else allowed here?
        }
    }

    String inDate = value;

    if (inDate.length() < 8) {
        // Invalid format
        throw new ParseException("Invalid date format '" + inDate + "'", inDate);
    }

    // Make sure all parts of the year are numeric.
    for (int i = 0; i < 8; i++) {
        char ch = inDate.charAt(i);
        if (ch < '0' || ch > '9') {
            throw new ParseException("Invalid date format '" + inDate + "'", inDate);
        }
    }
    year = Integer.parseInt(inDate.substring(0, 4));
    month = Integer.parseInt(inDate.substring(4, 6));
    day = Integer.parseInt(inDate.substring(6, 8));
    if (day < 1 || day > 31 || month < 1 || month > 12)
        throw new BogusDataException("Invalid date '" + inDate + "'", inDate);
    // Make sure day of month is valid for specified month
    if (year % 4 == 0) {
        // leap year
        if (day > leapMonthDays[month - 1]) {
            throw new BogusDataException("Invalid day of month '" + inDate + "'", inDate);
        }
    } else {
        if (day > monthDays[month - 1]) {
            throw new BogusDataException("Invalid day of month '" + inDate + "'", inDate);
        }
    }
    // TODO: parse time, handle localtime, handle timezone
    if (inDate.length() > 8) {
        // TODO make sure dateOnly == false
        if (inDate.charAt(8) == 'T') {
            try {
                hour = Integer.parseInt(inDate.substring(9, 11));
                minute = Integer.parseInt(inDate.substring(11, 13));
                second = Integer.parseInt(inDate.substring(13, 15));
                if (hour > 23 || minute > 59 || second > 59) {
                    throw new BogusDataException("Invalid time in date string '" + inDate + "'", inDate);
                }
                if (inDate.length() > 15) {
                    isUTC = inDate.charAt(15) == 'Z';
                }
            } catch (NumberFormatException nef) {
                throw new BogusDataException("Invalid time in date string '" + inDate + "' - " + nef, inDate);
            }
        } else {
            // Invalid format
            throw new ParseException("Invalid date format '" + inDate + "'", inDate);
        }
    } else {
        // Just date, no time
        dateOnly = true;
    }

    if (isUTC && !dateOnly) {
        // Use Joda Time to convert UTC to localtime
        DateTime utcDateTime = new DateTime(DateTimeZone.UTC);
        utcDateTime = utcDateTime.withDate(year, month, day).withTime(hour, minute, second, 0);
        DateTime localDateTime = utcDateTime.withZone(DateTimeZone.getDefault());
        year = localDateTime.getYear();
        month = localDateTime.getMonthOfYear();
        day = localDateTime.getDayOfMonth();
        hour = localDateTime.getHourOfDay();
        minute = localDateTime.getMinuteOfHour();
        second = localDateTime.getSecondOfMinute();
    } else if (tzid != null) {
        DateTimeZone tz = DateTimeZone.forID(tzid);
        if (tz != null) {
            // Convert to localtime
            DateTime utcDateTime = new DateTime(tz);
            utcDateTime = utcDateTime.withDate(year, month, day).withTime(hour, minute, second, 0);
            DateTime localDateTime = utcDateTime.withZone(DateTimeZone.getDefault());
            year = localDateTime.getYear();
            month = localDateTime.getMonthOfYear();
            day = localDateTime.getDayOfMonth();
            hour = localDateTime.getHourOfDay();
            minute = localDateTime.getMinuteOfHour();
            second = localDateTime.getSecondOfMinute();
            // Since we have converted to localtime, remove the TZID
            // attribute
            this.removeNamedAttribute("TZID");
        }
    }
    isUTC = false;

    // Add attribute that says date-only or date with time
    if (dateOnly)
        addAttribute("VALUE", "DATE");
    else
        addAttribute("VALUE", "DATE-TIME");

}

From source file:arjdbc.util.DateTimeUtils.java

License:Open Source License

@SuppressWarnings("deprecation")
public static IRubyObject newTime(final ThreadContext context, final Time time) {
    //if ( time == null ) return context.nil;
    final int hours = time.getHours();
    final int minutes = time.getMinutes();
    final int seconds = time.getSeconds();
    //final int offset = time.getTimezoneOffset();

    final DateTime dateTime;
    if (isDefaultTimeZoneUTC(context)) {
        dateTime = new DateTime(2000, 1, 1, hours, minutes, seconds, 0, DateTimeZone.UTC);
    } else {/*from  ww w  . j av a 2  s  .co m*/
        dateTime = new DateTime(2000, 1, 1, hours, minutes, seconds, 0);
    }
    return RubyTime.newTime(context.runtime, dateTime);
}

From source file:arjdbc.util.DateTimeUtils.java

License:Open Source License

@SuppressWarnings("deprecation")
public static IRubyObject newTime(final ThreadContext context, final Timestamp timestamp) {
    //if ( time == null ) return context.nil;

    final int year = timestamp.getYear() + 1900;
    final int month = timestamp.getMonth() + 1;
    final int day = timestamp.getDate();
    final int hours = timestamp.getHours();
    final int minutes = timestamp.getMinutes();
    final int seconds = timestamp.getSeconds();
    final int nanos = timestamp.getNanos(); // max 999-999-999

    final DateTime dateTime;
    if (isDefaultTimeZoneUTC(context)) {
        dateTime = new DateTime(year, month, day, hours, minutes, seconds, 0, DateTimeZone.UTC);
    } else {/*  w  ww  .ja va 2  s.c  o m*/
        dateTime = new DateTime(year, month, day, hours, minutes, seconds, 0);
    }
    return RubyTime.newTime(context.runtime, dateTime, nanos);
}

From source file:arjdbc.util.DateTimeUtils.java

License:Open Source License

public static RubyTime parseDateTime(final ThreadContext context, final String str)
        throws IllegalArgumentException {

    boolean hasDate = false;
    int year = 2000;
    int month = 1;
    int day = 1;//from   w ww .  j a v a 2s. c o  m
    boolean hasTime = false;
    int minute = 0;
    int hour = 0;
    int second = 0;
    int millis = 0;
    long nanos = 0;

    DateTimeZone zone = null;
    boolean bcEra = false;

    // We try to parse these fields in order; all are optional
    // (but some combinations don't make sense, e.g. if you have
    //  both date and time then they must be whitespace-separated).
    // At least one of date and time must be present.

    //   leading whitespace
    //   yyyy-mm-dd
    //   whitespace
    //   hh:mm:ss
    //   whitespace
    //   timezone in one of the formats:  +hh, -hh, +hh:mm, -hh:mm
    //   whitespace
    //   if date is present, an era specifier: AD or BC
    //   trailing whitespace

    final int len = str.length();

    int start = nonSpaceIndex(str, 0, len); // Skip leading whitespace
    int end = nonDigitIndex(str, start, len);

    // Possibly read date.
    if (end < len && str.charAt(end) == '-') {
        hasDate = true;

        // year
        year = extractIntValue(str, start, end);
        start = end + 1; // Skip '-'

        // month
        end = nonDigitIndex(str, start, len);
        month = extractIntValue(str, start, end);

        char sep = str.charAt(end);
        if (sep != '-') {
            throw new IllegalArgumentException("expected date to be dash-separated, got '" + sep + "'");
        }

        start = end + 1; // Skip '-'

        // day of month
        end = nonDigitIndex(str, start, len);
        day = extractIntValue(str, start, end);

        start = nonSpaceIndex(str, end, len); // Skip trailing whitespace
    }

    // Possibly read time.
    if (start < len && Character.isDigit(str.charAt(start))) {
        hasTime = true;

        // hours
        end = nonDigitIndex(str, start, len);
        hour = extractIntValue(str, start, end);

        //sep = str.charAt(end);
        //if ( sep != ':' ) {
        //    throw new IllegalArgumentException("expected time to be colon-separated, got '" + sep + "'");
        //}

        start = end + 1; // Skip ':'

        // minutes
        end = nonDigitIndex(str, start, len);
        minute = extractIntValue(str, start, end);

        //sep = str.charAt(end);
        //if ( sep != ':' ) {
        //    throw new IllegalArgumentException("expected time to be colon-separated, got '" + sep + "'");
        //}

        start = end + 1; // Skip ':'

        // seconds
        end = nonDigitIndex(str, start, len);
        second = extractIntValue(str, start, end);
        start = end;

        // Fractional seconds.
        if (start < len && str.charAt(start) == '.') {
            end = nonDigitIndex(str, start + 1, len); // Skip '.'
            int numlen = end - (start + 1);
            if (numlen <= 3) {
                millis = extractIntValue(str, start + 1, end);
                for (; numlen < 3; ++numlen)
                    millis *= 10;
            } else {
                nanos = extractIntValue(str, start + 1, end);
                for (; numlen < 9; ++numlen)
                    nanos *= 10;
            }

            start = end;
        }

        start = nonSpaceIndex(str, start, len); // Skip trailing whitespace
    }

    // Possibly read timezone.
    char sep = start < len ? str.charAt(start) : '\0';
    if (sep == '+' || sep == '-') {
        int zoneSign = (sep == '-') ? -1 : 1;
        int hoursOffset, minutesOffset, secondsOffset;

        end = nonDigitIndex(str, start + 1, len); // Skip +/-
        hoursOffset = extractIntValue(str, start + 1, end);
        start = end;

        if (start < len && str.charAt(start) == ':') {
            end = nonDigitIndex(str, start + 1, len); // Skip ':'
            minutesOffset = extractIntValue(str, start + 1, end);
            start = end;
        } else {
            minutesOffset = 0;
        }

        secondsOffset = 0;
        if (start < len && str.charAt(start) == ':') {
            end = nonDigitIndex(str, start + 1, len); // Skip ':'
            secondsOffset = extractIntValue(str, start + 1, end);
            start = end;
        }

        // Setting offset does not seem to work correctly in all
        // cases.. So get a fresh calendar for a synthetic timezone
        // instead

        int offset = zoneSign * hoursOffset * 60;
        if (offset < 0) {
            offset = offset - Math.abs(minutesOffset);
        } else {
            offset = offset + minutesOffset;
        }
        offset = (offset * 60 + secondsOffset) * 1000;
        zone = DateTimeZone.forOffsetMillis(offset);

        start = nonSpaceIndex(str, start, len); // Skip trailing whitespace
    }

    if (hasDate && start < len) {
        final char e1 = str.charAt(start);
        if (e1 == 'A' && str.charAt(start + 1) == 'D') {
            bcEra = false;
            start += 2;
        } else if (e1 == 'B' && str.charAt(start + 1) == 'C') {
            bcEra = true;
            start += 2;
        }
    }

    if (start < len) {
        throw new IllegalArgumentException(
                "trailing junk: '" + str.substring(start, len - start) + "' on '" + str + "'");
    }
    if (!hasTime && !hasDate) {
        throw new IllegalArgumentException("'" + str + "' has neither date nor time");
    }

    if (bcEra)
        year = -1 * year;

    if (zone == null) {
        zone = isDefaultTimeZoneUTC(context) ? DateTimeZone.UTC : DateTimeZone.getDefault();
    }

    DateTime dateTime = new DateTime(year, month, day, hour, minute, second, millis, zone);
    return RubyTime.newTime(context.runtime, dateTime, nanos);
}