Example usage for org.joda.time DateTime withLaterOffsetAtOverlap

List of usage examples for org.joda.time DateTime withLaterOffsetAtOverlap

Introduction

In this page you can find the example usage for org.joda.time DateTime withLaterOffsetAtOverlap.

Prototype

public DateTime withLaterOffsetAtOverlap() 

Source Link

Document

Returns a copy of this ZonedDateTime changing the zone offset to the later of the two valid offsets at a local time-line overlap.

Usage

From source file:org.jadira.usertype.dateandtime.joda.PersistentDateTimeAndZoneWithOffset.java

License:Apache License

@Override
protected DateTime fromConvertedColumns(Object[] convertedColumns) {

    LocalDateTime datePart = (LocalDateTime) convertedColumns[0];
    DateTimeZoneWithOffset offset = (DateTimeZoneWithOffset) convertedColumns[1];

    DateTime result;

    if (datePart == null) {
        result = null;// w w  w. j  av a 2s .  co  m
    } else {
        result = datePart.toDateTime(databaseZone == null ? offset.getStandardDateTimeZone() : databaseZone);

        if (databaseZone != null) {
            result = result.withZone(offset.getStandardDateTimeZone());
        }
    }

    // Handling DST rollover
    if (result != null && offset.getOffsetDateTimeZone() != null && offset.getStandardDateTimeZone()
            .getOffset(result) > offset.getOffsetDateTimeZone().getOffset(result)) {
        return result.withLaterOffsetAtOverlap();
    }

    return result;
}

From source file:org.jruby.RubyTime.java

License:LGPL

private static RubyTime createTime(IRubyObject recv, IRubyObject[] args, boolean gmt, boolean utcOffset) {
    Ruby runtime = recv.getRuntime();/*from   ww w . jav  a 2 s.co  m*/
    int len = ARG_SIZE;
    boolean isDst = false;
    boolean setTzRelative = false;
    long nanos = 0;

    DateTimeZone dtz;
    if (gmt) {
        dtz = DateTimeZone.UTC;
    } else if (args.length == 10 && args[9] instanceof RubyString) {
        if (utcOffset) {
            dtz = getTimeZoneFromUtcOffset(runtime, args[9]);
            setTzRelative = true;
        } else {
            dtz = getTimeZoneFromString(runtime, args[9].toString());
        }
    } else if (args.length == 10 && args[9].respondsTo("to_int")) {
        IRubyObject offsetInt = args[9].callMethod(runtime.getCurrentContext(), "to_int");
        dtz = getTimeZone(runtime, ((RubyNumeric) offsetInt).getLongValue());
    } else {
        dtz = getLocalTimeZone(runtime);
    }

    if (args.length == 10) {
        if (args[8] instanceof RubyBoolean)
            isDst = args[8].isTrue();

        args = new IRubyObject[] { args[5], args[4], args[3], args[2], args[1], args[0], runtime.getNil() };
    } else {
        // MRI accepts additional wday argument which appears to be ignored.
        len = args.length;

        if (len < ARG_SIZE) {
            IRubyObject[] newArgs = new IRubyObject[ARG_SIZE];
            System.arraycopy(args, 0, newArgs, 0, args.length);
            for (int i = len; i < ARG_SIZE; i++) {
                newArgs[i] = runtime.getNil();
            }
            args = newArgs;
            len = ARG_SIZE;
        }
    }

    if (args[0] instanceof RubyString) {
        args[0] = RubyNumeric.str2inum(runtime, (RubyString) args[0], 10, false);
    }

    int year = (int) RubyNumeric.num2long(args[0]);
    int month = 1;

    if (len > 1) {
        if (!args[1].isNil()) {
            IRubyObject tmp = args[1].checkStringType();
            if (!tmp.isNil()) {
                String monthString = tmp.toString().toLowerCase();
                Integer monthInt = MONTHS_MAP.get(monthString);

                if (monthInt != null) {
                    month = monthInt;
                } else {
                    try {
                        month = Integer.parseInt(monthString);
                    } catch (NumberFormatException nfExcptn) {
                        throw runtime.newArgumentError("Argument out of range.");
                    }
                }
            } else {
                month = (int) RubyNumeric.num2long(args[1]);
            }
        }
        if (1 > month || month > 12) {
            throw runtime.newArgumentError("Argument out of range: for month: " + month);
        }
    }

    int[] int_args = { 1, 0, 0, 0, 0, 0 };

    for (int i = 0; int_args.length >= i + 2; i++) {
        if (!args[i + 2].isNil()) {
            if (!(args[i + 2] instanceof RubyNumeric)) {
                if (args[i + 2].respondsTo("to_int")) {
                    args[i + 2] = args[i + 2].callMethod(runtime.getCurrentContext(), "to_int");
                } else {
                    args[i + 2] = args[i + 2].callMethod(runtime.getCurrentContext(), "to_i");
                }
            }

            int_args[i] = RubyNumeric.num2int(args[i + 2]);
        }
    }

    // Validate the times
    // Complying with MRI behavior makes it a little bit complicated. Logic copied from:
    // https://github.com/ruby/ruby/blob/trunk/time.c#L2609
    if ((int_args[0] < 1 || int_args[0] > 31) || (int_args[1] < 0 || int_args[1] > 24)
            || (int_args[1] == 24 && (int_args[2] > 0 || int_args[3] > 0))
            || (int_args[2] < 0 || int_args[2] > 59) || (int_args[3] < 0 || int_args[3] > 60)) {
        throw runtime.newArgumentError("argument out of range.");
    }

    DateTime dt;
    // set up with min values and then add to allow rolling over
    try {
        dt = new DateTime(year, 1, 1, 0, 0, 0, 0, DateTimeZone.UTC);

        dt = dt.plusMonths(month - 1).plusDays(int_args[0] - 1).plusHours(int_args[1]).plusMinutes(int_args[2])
                .plusSeconds(int_args[3]);

        // 1.9 will observe fractional seconds *if* not given usec
        if (!args[5].isNil() && args[6].isNil()) {
            double secs = RubyFloat.num2dbl(args[5]);
            int int_millis = (int) (secs * 1000) % 1000;
            dt = dt.plusMillis(int_millis);
            nanos = ((long) (secs * 1000000000) % 1000000);
        }

        dt = dt.withZoneRetainFields(dtz);

        // If we're at a DST boundary, we need to choose the correct side of the boundary
        if (isDst) {
            final DateTime beforeDstBoundary = dt.withEarlierOffsetAtOverlap();
            final DateTime afterDstBoundary = dt.withLaterOffsetAtOverlap();

            final int offsetBeforeBoundary = dtz.getOffset(beforeDstBoundary);
            final int offsetAfterBoundary = dtz.getOffset(afterDstBoundary);

            // If the time is during DST, we need to pick the time with the highest offset
            dt = offsetBeforeBoundary > offsetAfterBoundary ? beforeDstBoundary : afterDstBoundary;
        }
    } catch (org.joda.time.IllegalFieldValueException e) {
        throw runtime.newArgumentError("time out of range");
    }

    RubyTime time = new RubyTime(runtime, (RubyClass) recv, dt);
    // Ignores usec if 8 args (for compatibility with parsedate) or if not supplied.
    if (args.length != 8 && !args[6].isNil()) {
        boolean fractionalUSecGiven = args[6] instanceof RubyFloat || args[6] instanceof RubyRational;

        if (fractionalUSecGiven) {
            double micros = RubyNumeric.num2dbl(args[6]);
            time.dt = dt.withMillis(dt.getMillis() + (long) (micros / 1000));
            nanos = ((long) (micros * 1000) % 1000000);
        } else {
            int usec = int_args[4] % 1000;
            int msec = int_args[4] / 1000;

            if (int_args[4] < 0) {
                msec -= 1;
                usec += 1000;
            }
            time.dt = dt.withMillis(dt.getMillis() + msec);
            time.setUSec(usec);
        }
    }

    if (nanos != 0)
        time.setNSec(nanos);

    time.callInit(IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
    time.setIsTzRelative(setTzRelative);
    return time;
}