PHP8 —— New String Helpers

新增了三个字符串函数,str_starts_with, str_ends_with, str_contains, PHP 的函数这么方便,很难想象竟然一直没有这几个。 str_starts_with 判断字符串是否以另一个字符串开头,在PHP7以及之前 $id = 'inv_abcdefgh'; $result = strpos($id, 'inv_') === 0; var_dump($result); // true PHP8 中可以直接这么写 $result = str_starts_with($id, 'inv_'); str_ends_with 判断字符串是否以另外一个字符串结尾,在 PHP7 及之前,比较麻烦,通常是这么写 $id = 'abcd_inv'; $result = strpos(strrev($id), strrev('_inv')) === 0; 或者 $result = substr($id, -1 * strlen('_inv')) === '_inv'; 或者上正则吧 $result = preg_match('/_inv$/', $id) === 1; 看起来都是比较麻烦的。PHP8 里面可以简化成下面这样了 $id = 'abcd_inv'; $result = str_ends_with($id, '_ind'); str_contains 字符串包含,PHP8 之前一般就是 strpos 来实现了 $url = 'https://example?for=bar'; $result = strpos($url, '?') !== FALSE; PHP8 就直接一点 $result = str_contains($url, '?');

Java学习笔记 —— 使用现有实例创建 Dates 和 Times 对象

新的Date-Time API的特点之一是所有实例都是不可变的。 创建LocalDate,LocalTime,LocalDateTime或ZonedDateTime后,将无法再对其进行更改。 这具有使它们线程安全的巨大优势,但是如果你想基于现有实例创建一个新实例,该怎么办?
LocalDate类具有几种从日期中添加和减去值的方法。 具体来说,有:

  • LocalDate plusDays(long daysToAdd)
  • LocalDate plusWeeks(long weeksToAdd)
  • LocalDate plusMonths(long monthsToAdd) • LocalDate plusYears(long yearsToAdd)

每个方法都基于当前 date 增加或减少天数后返回一个新的LocalDate,LocalTime类具有类似的方法:

  • LocalTime plusNanos(long nanosToAdd)
  • LocalTime plusSeconds(long secondsToAdd)
  • LocalTime plusMinutes(long minutesToAdd)
  • LocalTime plusHours(long hoursToAdd)

同样,原始实例增加了一定时间后返回一个新实例。 LocalDateTime具有LocalDate和LocalTime的所有方法。 程序示例如下:

    @Test
    public void localDatePlus() throws Exception {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = LocalDate.of(2017, Month.FEBRUARY, 2);
        LocalDate end = start.plusDays(3);
        assertEquals("2017-02-05", end = start.plusWeeks(5);
        assertEquals("2017-03-09", end = start.plusMonths(7);
        assertEquals("2017-09-02", end = start.plusYears(2);
        assertEquals("2019-02-02",
                @Test
                        end.format(formatter));
        end.format(formatter));
        end.format(formatter));
        end.format(formatter));
    }

    public void localTimePlus() throws Exception {
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_TIME;
        LocalTime start = LocalTime.of(11, 30, 0, 0);
        LocalTime end = start.plusNanos(1_000_000);
        assertEquals("11:30:00.001", end.format(formatter));
        end = start.plusSeconds(20);
        assertEquals("11:30:20", end.format(formatter));
        end = start.plusMinutes(45);
        assertEquals("12:15:00", end.format(formatter));
        end = start.plusHours(5);
        assertEquals("16:30:00", end.format(formatter));
    }

LocalDateTime 还有一些额外plus和minus的方法:

  • LocalDateTime plus(long amountToAdd, TemporalUnit unit)
  • LocalDateTime plus(TemporalAmount amountToAdd)
  • LocalDateTime minus(long amountToSubtract, TemporalUnit unit)
  • LocalDateTime minus(TemporalAmount amountToSubtract)

本质上minus方法是使用负数调用对等的plus方法。

对于接受TemporalAmount的方法,参数通常为Period或Duration,也是可以是实现TemporalAmount接口的任何类型。 该接口具有称为addTo和subtractFrom的方法:

  • Temporal addTo(Temporal temporal)
  • Temporal subtractFrom(Temporal temporal)

如果追踪调用栈,可以发现调用 minus 时,委托到使用相反数调用 plus, 之后委托到TemporalAmount.addTo(Temporal),然后实际调用发生在plus(long, TemporalUnit)

    @Test
    public void plus_minus() throws Exception {
        Period period = Period.of(2, 3, 4); // 2 years, 3 months, 4 days 
        LocalDateTime start = LocalDateTime.of(2017, Month.FEBRUARY, 2, 11, 30); 
        LocalDateTime end = start.plus(period);
        assertEquals("2019-05-06T11:30:00", end.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        end = start.plus(3, ChronoUnit.HALF_DAYS);
        assertEquals("2017-02-03T23:30:00",
                end.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        end = start.minus(period);
        assertEquals("2014-10-29T11:30:00",
                end.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        end = start.minus(2, ChronoUnit.CENTURIES);
        assertEquals("1817-02-02T11:30:00",
                end.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        end = start.plus(3, ChronoUnit.MILLENNIA);
        assertEquals("5017-02-02T11:30:00",
                end.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
    }

最后,每个类上都有一系列with方法,可用于一次更改一个字段。范围从 withNano 一直到 withYear。 以 LocalDateTime 为例:

  • LocalDateTime withNano(int nanoOfSecond)
  • LocalDateTime withSecond(int second)
  • LocalDateTime withMinute(int minute)
  • LocalDateTime withHour(int hour) LocalDateTime
  • withDayOfMonth(int dayOfMonth) LocalDateTime
  • withDayOfYear(int dayOfYear) LocalDateTime
  • withMonth(int month) LocalDateTime
  • withYear(int year)

同时还有接受 TemporalAdjuster 或者 TemporalField 的with方法:

  • LocalDateTime with(TemporalAdjuster adjuster)
  • LocalDateTime with(TemporalField field, long newValue)

评论

此博客中的热门博文

D3js Data-binding basics

JavaScript 数据类型

Vue3新特性(1) —— Vite