开发者

springboot之Duration(java.time.Duration)在yml properties中的配置方式

开发者 https://www.devze.com 2023-12-19 10:34 出处:网络 作者: hank009
目录内部源码详解简单格式ISO-8601格式格式说明详解源码介绍总结在新版本的spring boot中的Redis的时间相关的配置使用了 Java.time.Duration类
目录
  • 内部源码详解
  • 简单格式
  • ISO-8601格式
    • 格式说明
    • 详解
    • 源码介绍
  • 总结

    在新版本的spring boot中的Redis的时间相关的配置使用了 Java.time.Duration类

    在配置时间时发现与老版本不同,就研究了下,发现使用了新的方式配置时间,这里记录下

    从源码中可以看出 时间配置应该诸如: 1s 1.5s 0s 0.001S  1h 2d 1m 1M -PT0.001S P1DT2H15M(1天+2小时+15分钟) 形式

    内部源码详解

    1. 我们可通过源码找到springboot的转换器StringToDurationConverter,其中转换的核心代码使用了DurationStyle定义了时间格式:

    	private Duration convert(String source, DurationStyle style, ChronoUnit unit) {
    		style = (style != null) ? style : DurationStyle.detect(source);
    		return style.parse(source, unit);
    	}

    2. 我们在DurationStyle中可以看到有两种格式(简单格式和ISO-8601格式)的支持:

    	/**
    	 * Simple formatting, for example '1s'.(简单格式)
    	 */
    	SIMPLE("^([+-]?\\d+)([a-zA-Z]{0,2})$") {
     
    		......
    	},
     
    	/**
    	 * ISO-8601 formatting. (ISO-8601格式)
    	 */
    	ISO8601("^[+-]?[pP].*$") {
     
    		......
    	};

    简单格式

    DurationStyle中简单格式支持的单位定义在下方的Unit枚举中:

    • ns: 纳秒 
    • us: 微秒 
    • ms: 毫秒 
    • s: 秒
    • m: 分钟 
    • h: 小时 
    • d: 天; (都不区分大小写)
    	/**
    	 * Units that we support.
    	 */
    	enum Unit {
     
    		/**
    		 * Nanoseconds.
    		 */
    		NANOS(ChronoUnit.NANOS, "ns", Duration::toNanos),
     
    		/**
    		 * Microseconds.
    		 */
    		MICROS(ChronoUnit.MICROS, "us", (duration) -> duration.toNanos() / 1000L),
     
    		/**
    		 * Milliseconds.
    		 */
    		MILLIS(ChronoUnit.MILLIS, "ms", Duration::toMillis),
     
    		/**
    		 * Seconds.
    		 */
    		SECONDS(ChronoUnit.SECONDS, "s", Duration::getSeconds),
     
    		/**
    		 * Minutes.
    		 */
    		MINUTES(ChronoUnit.MINUTES, "m", Duration::toMinutes),
     
    		/**
    		 * Hours.
    		 */
    		HOURS(ChronoUnit.HOURS, "h", Duration::toHours),
     
    		/**
    		 * Days.
    		 */
    		DAYS(ChronoUnit.DAYS, "d", Duration::toDays);

    ISO-8601格式

    格式说明

    采用ISO-8601时间格式。格式为:PnYnMnDTnHnMnS   (n为个数)

    例如:P1Y2M3DT4H5M6.7S = 1年2个月3天4小时5分钟6.7秒

    P:开始标记

    • 1Y:1年 (Duration中没有)
    • 2M:2个月 (Duration中没有)
    • 3D:3天

    T:日期和时间的分割标记

    • 4H:4个小时
    • 5M:5分钟
    • 6.7S:6.7秒

    注意: 这里的Duration只有D,H,M,S没有Y,M

    详解

    1."P", "D", "H", "M" 和 "S"可以是大写或者小写(建议大写)

    2.可以用“-”表示负数

    示例:

              "PT20.345S" -- parses as "20.345 seconds"
              "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
              "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
              "P2D"       -- parses as "2 days" python(where a day is 24 hours or 86400 seconds)
              "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
              "PT-6H3M"    --python parses as "-6 hours and +3 minutes"
              "-PT6H3M"    -- parses as "-6 hours and -3 minutes"
              "-PT-6H+3M"  -- parses as "+6 hours and -3 minutes"

    源码介绍

    ISO-8601格式在DurationStyle中直接是使用Duration.parse方法进行处理,Duration.parse方法的

    定义如下:

    springboot之Duration(java.time.Duration)在yml properties中的配置方式

    /**
         * Obtains a {@code Duration} from a text string such as {@code PnDTnHnMn.nS}.
         * <p>
         * This will parse a textual representation of a duration, including the
         * string produced by {@code toString()}. The formats accepted are based
         * on the ISO-8601 duration format {@code PnDTnHnMn.nS} with days
         * considered to be exactly 24 hours.
         * <p>
         * The string starts with an optional sign, denoted by the ASCII negative
         * or positive symbol. If negative, the whole period is negated.
         * The ASCII letter "P" is next in upper or lower case.
         * There are then four sections, each consisting of a number and a suffix.
         * The sections have suffixes in ASCII of "D", "H", "M" and "S" for
         * days, hours, minutes and seconds, accepted in upper or lower case.
         * The suffixes must occur in order. The ASCII letter "T" must occur before
         * the first occurrence, if any, of an hour, minute or second section.
         * At least one of the four sections must be present, and if "T" is present
         * there must be at least one section after the "T".
         * The number part of each section must consist of one or more ASCII digits.
         * The number may be prefixed by the ASCII negative or positive symbol.
         * The number of days, hours and minutes must parse to an {@code long}.
         * The number of seconds must parse to an {@code long} with optional fraction.
         * The decimal point may be either a dot or a comma.
         * The fractional part may have编程客栈 from zero to 9 digits.
         * <p&gwww.devze.comt;
         * The leading plus/minus sign, and negative values for other units are
         * not part of the ISO-8601 standard.
         * <p>
         * Examples:
         * <pre>
         *    "PT20.345S" -- parses as "20.345 seconds"
         *    "PT15M"  编程   -- parses as "15 minutes" (where a minute is 60 seconds)
         *    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
         *    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
         *    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
         *    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
         *    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
         *    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
         * </pre>
         *
         * @param text  the text to parse, not null
         * @return the parsed duration, not null
         * @throws DateTimeParseException if the text cannot be parsed to a duration
         */
        public static Duration parse(CharSequence text) {
            Objects.requireNonNull(text, "text");
            Matcher matcher = PATTERN.matcher(text);
            if (matcher.matches()) {
                // check for letter T but no time sections
                if ("T".equals(matcher.group(3)) == false) {
                    boolean negate = "-".equals(matcher.group(1));
                    String dayMatch = matcher.group(2);
                    String hourMatch = matcher.group(4);
                    String minuteMatch = matcher.group(5);
                    String secondMatch = matcher.group(6);
                    String fractionMatch = matcher.group(7);
                    if (dayMatch != null || hourMatch != null || minuteMatch != null || secondMatch != null) {
                        long daysAsSecs = parseNumber(text, dayMatch, SECONDS_PER_DAY, "days");
                        long hoursAsSecs = parseNumber(text, hourMatch, SECONDS_PER_HOUR, "hours");
                        long minsAsSecs = parseNumber(text, minuteMatch, SECONDS_PER_MINUTE, "minutes");
                        long seconds = parseNumber(text, secondMatch, 1, "seconds");
                        int nanos = parseFraction(text,  fractionMatch, seconds < 0 ? -1 : 1);
                        try {
                            return create(negate, daysAsSecs, hoursAsSecs, minsAsSecs, seconds, nanos);
                        } catch (ArithmeticException ex) {
                            throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: overflow", text, 0).initCause(ex);
                        }
                    }
                }
            }
            throw new DateTimeParseException("Text cannot be parsed to a Duration", text, 0);
        }

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号