001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.test.generator.impl;
017
018import de.cuioss.test.generator.Generators;
019import de.cuioss.test.generator.TypedGenerator;
020
021import java.time.LocalDateTime;
022import java.time.ZoneId;
023import java.time.ZoneOffset;
024
025import static java.time.ZoneId.getAvailableZoneIds;
026
027/**
028 * Generates {@link ZoneOffset} instances based on the available system time zones.
029 * This generator creates offsets by sampling from all available zone IDs and
030 * extracting their current offsets.
031 * 
032 * <p>Features:</p>
033 * <ul>
034 *   <li>Uses all system-available zone IDs ({@link ZoneId#getAvailableZoneIds()})</li>
035 *   <li>Generates valid offsets based on current time</li>
036 *   <li>Covers both positive and negative offsets</li>
037 *   <li>Thread-safe implementation</li>
038 * </ul>
039 * 
040 * <p><em>Example usage:</em></p>
041 * <pre>
042 * {@code
043 * // Create a generator
044 * var generator = new ZoneOffsetGenerator();
045 * 
046 * // Generate single values
047 * ZoneOffset offset = generator.next();
048 * 
049 * // Generate collections
050 * var collectionGen = new CollectionGenerator&lt;&gt;(generator);
051 * List&lt;ZoneOffset&gt; offsets = collectionGen.list(5); // List of 5 offsets
052 * }
053 * </pre>
054 * 
055 * <p>This generator is particularly useful for testing:</p>
056 * <ul>
057 *   <li>Time zone offset calculations</li>
058 *   <li>UTC conversions</li>
059 *   <li>Date-time formatting with offsets</li>
060 *   <li>International time handling</li>
061 * </ul>
062 *
063 * @author Eugen Fischer
064 * @see ZoneOffset
065 * @see ZoneId
066 * @see LocalDateTime
067 */
068public class ZoneOffsetGenerator implements TypedGenerator<ZoneOffset> {
069
070    private static final TypedGenerator<ZoneId> ZONE_IDS_GEN = Generators.fixedValues(ZoneId.class,
071            getAvailableZoneIds().stream().map(ZoneId::of).toList());
072
073    @Override
074    public ZoneOffset next() {
075        return LocalDateTime.now().atZone(ZONE_IDS_GEN.next()).getOffset();
076    }
077
078    @Override
079    public Class<ZoneOffset> getType() {
080        return ZoneOffset.class;
081    }
082
083}