1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.function.library;
7   
8   import java.time.Duration;
9   import java.time.ZoneId;
10  import java.time.ZoneOffset;
11  import java.time.ZonedDateTime;
12  import java.util.List;
13  
14  import dev.metaschema.core.metapath.DynamicContext;
15  import dev.metaschema.core.metapath.MetapathConstants;
16  import dev.metaschema.core.metapath.function.IFunction;
17  import dev.metaschema.core.metapath.item.IItem;
18  import dev.metaschema.core.metapath.item.ISequence;
19  import dev.metaschema.core.metapath.item.atomic.IDayTimeDurationItem;
20  import dev.metaschema.core.util.ObjectUtils;
21  import edu.umd.cs.findbugs.annotations.NonNull;
22  
23  /**
24   * Implements <a href=
25   * "https://www.w3.org/TR/xpath-functions-31/#func-implicit-timezone">fn:implicit-timezone</a>.
26   */
27  public final class FnImplicitTimezone {
28    private static final String NAME = "implicit-timezone";
29    @NonNull
30    static final IFunction SIGNATURE = IFunction.builder()
31        .name(NAME)
32        .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS)
33        .deterministic()
34        .contextDependent()
35        .focusIndependent()
36        .returnType(IDayTimeDurationItem.type())
37        .returnOne()
38        .functionHandler(FnImplicitTimezone::execute)
39        .build();
40  
41    private FnImplicitTimezone() {
42      // disable construction
43    }
44  
45    @SuppressWarnings("unused")
46    @NonNull
47    private static ISequence<IDayTimeDurationItem> execute(@NonNull IFunction function,
48        @NonNull List<ISequence<?>> arguments,
49        @NonNull DynamicContext dynamicContext,
50        IItem focus) {
51      return ISequence.of(fnImplicitTimezone(dynamicContext));
52    }
53  
54    /**
55     * Implements <a href=
56     * "https://www.w3.org/TR/xpath-functions-31/#func-implicit-timezone">fn:implicit-timezone</a>.
57     *
58     * @param dynamicContext
59     *          the dynamic evaluation context
60     * @return the current date
61     */
62    @NonNull
63    public static IDayTimeDurationItem fnImplicitTimezone(@NonNull DynamicContext dynamicContext) {
64      // FIXME: support implicit timezone
65      ZoneId timezone = dynamicContext.getImplicitTimeZone();
66      ZonedDateTime now = dynamicContext.getCurrentDateTime().withZoneSameInstant(timezone);
67      return IDayTimeDurationItem.valueOf(ObjectUtils.notNull(
68          Duration.between(
69              now,
70              now.withZoneSameLocal(ZoneOffset.UTC))));
71    }
72  }