@Override
    public Optional<ShardingConditionValue> generate(final BetweenExpression predicate, final Column column, final List<Object> params, final TimestampServiceRule timestampServiceRule) {
        ConditionValue betweenConditionValue = new ConditionValue(predicate.getBetweenExpr(), params);
        ConditionValue andConditionValue = new ConditionValue(predicate.getAndExpr(), params);
        Optional<Comparable<?>> betweenValue = betweenConditionValue.getValue();
        Optional<Comparable<?>> andValue = andConditionValue.getValue();
        List<Integer> parameterMarkerIndexes = new ArrayList<>(2);
        betweenConditionValue.getParameterMarkerIndex().ifPresent(parameterMarkerIndexes::add);
        andConditionValue.getParameterMarkerIndex().ifPresent(parameterMarkerIndexes::add);
        if (betweenValue.isPresent() && andValue.isPresent()) {
            return Optional.of(new RangeShardingConditionValue<>(column.getName(), column.getTableName(), SafeNumberOperationUtils.safeClosed(betweenValue.get(), andValue.get()),
                    parameterMarkerIndexes));
        }
        Timestamp timestamp = timestampServiceRule.getTimestamp();
        if (!betweenValue.isPresent() && ExpressionConditionUtils.isNowExpression(predicate.getBetweenExpr())) {
            betweenValue = Optional.of(timestamp);
        }
        if (!andValue.isPresent() && ExpressionConditionUtils.isNowExpression(predicate.getAndExpr())) {
            andValue = Optional.of(timestamp);
        }
        if (!betweenValue.isPresent() || !andValue.isPresent()) {
            return Optional.empty();
        }
        return Optional.of(new RangeShardingConditionValue<>(column.getName(), column.getTableName(), Range.closed(betweenValue.get(), andValue.get()), parameterMarkerIndexes));
    }
@SuppressWarnings("unchecked")
    @Test
    void assertGenerateNowConditionValue() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, 1);
        final Date after = calendar.getTime();
        ExpressionSegment betweenSegment = new CommonExpressionSegment(0, 0, "now()");
        ExpressionSegment andSegment = new CommonExpressionSegment(0, 0, "now()");
        BetweenExpression value = new BetweenExpression(0, 0, null, betweenSegment, andSegment, false);
        Optional<ShardingConditionValue> shardingConditionValue = generator.generate(value, column, new LinkedList<>(), timestampServiceRule);
        assertTrue(shardingConditionValue.isPresent());
        RangeShardingConditionValue<Date> rangeShardingConditionValue = (RangeShardingConditionValue<Date>) shardingConditionValue.get();
        assertThat(rangeShardingConditionValue.getColumnName(), is(column.getName()));
        assertThat(rangeShardingConditionValue.getTableName(), is(column.getTableName()));
        assertTrue(rangeShardingConditionValue.getValueRange().upperEndpoint().before(after));
        assertTrue(rangeShardingConditionValue.getParameterMarkerIndexes().isEmpty());
    }