package org.embulk.spi.time; import org.jruby.runtime.ThreadContext; import java.util.HashMap; import java.util.List; import static org.embulk.spi.time.StrptimeParser.FormatBag.has; import static org.jruby.RubyRational.newRationalCanonicalize; /** * This class has {@code StrptimeParser} and provides methods that are calls from JRuby. * * TODO * This class is tentatively required for executing test/mri/date/test_date_strptime.rb * (#617). The {@code StrptimeParser} and {@code RubyDateParser} will be merged into * JRuby (jruby/jruby#4591). embulk-jruby-strptime is removed when Embulk start using * the JRuby that bundles embulk-jruby-strptime. */ public class RubyDateParser { private final StrptimeParser strptimeParser; public RubyDateParser() { this.strptimeParser = new StrptimeParser(); } /** * Date._strptime method in JRuby 9.1.5.0's lib/ruby/stdlib/date/format.rb is replaced * with this method. This is Java implementation of date__strptime method in MRI 2.3.1's * ext/date/date_strptime.c. * @see format.rb * @see date_strptime.c */ public HashMap parse(ThreadContext context, final String format, final String text) { final List compiledPattern = strptimeParser.compilePattern(format); final StrptimeParser.FormatBag bag = strptimeParser.parse(compiledPattern, text); if (bag != null) { return convertFormatBagToHash(context, bag); } else { return null; } } private HashMap convertFormatBagToHash(ThreadContext context, StrptimeParser.FormatBag bag) { final HashMap map = new HashMap<>(); if (has(bag.getMDay())) { map.put("mday", bag.getMDay()); } if (has(bag.getWDay())) { map.put("wday", bag.getWDay()); } if (has(bag.getCWDay())) { map.put("cwday", bag.getCWDay()); } if (has(bag.getYDay())) { map.put("yday", bag.getYDay()); } if (has(bag.getCWeek())) { map.put("cweek", bag.getCWeek()); } if (has(bag.getCWYear())) { map.put("cwyear", bag.getCWYear()); } if (has(bag.getMin())) { map.put("min", bag.getMin()); } if (has(bag.getMon())) { map.put("mon", bag.getMon()); } if (has(bag.getHour())) { map.put("hour", bag.getHour()); } if (has(bag.getYear())) { map.put("year", bag.getYear()); } if (has(bag.getSec())) { map.put("sec", bag.getSec()); } if (has(bag.getWNum0())) { map.put("wnum0", bag.getWNum0()); } if (has(bag.getWNum1())) { map.put("wnum1", bag.getWNum1()); } if (bag.getZone() != null) { map.put("zone", bag.getZone()); int offset = TimeZoneConverter.dateZoneToDiff(bag.getZone()); if (offset != Integer.MIN_VALUE) { map.put("offset", offset); } } if (has(bag.getSecFraction())) { map.put("sec_fraction", newRationalCanonicalize(context, bag.getSecFraction(), (long)Math.pow(10, bag.getSecFractionSize()))); } if (bag.hasSeconds()) { if (has(bag.getSecondsSize())) { map.put("seconds", newRationalCanonicalize(context, bag.getSeconds(), (long) Math.pow(10, bag.getSecondsSize()))); } else { map.put("seconds", bag.getSeconds()); } } if (has(bag.getMerid())) { map.put("_merid", bag.getMerid()); } if (has(bag.getCent())) { map.put("_cent", bag.getCent()); } if (bag.getLeftover() != null) { map.put("leftover", bag.getLeftover()); } return map; } }