about Set Session Time Zone

1. How to check the session time zone ?

The new SESSIONTIMEZONE built-in
SQL function returns the value of the current session's time zone.

SQL> SELECT SESSIONTIMEZONE FROM DUAL;

SESSIONTIMEZONE
---------------
+01:00


2. How to set the session time zone ?

The session time zone can be set to:
- O/S local time zone
- Database time zone
- An absolute offset
- A named region

1). The first method consists to use one of the following ALTER SESSION SET TIME_ZONE statements:
SQL> ALTER SESSION SET TIME_ZONE = local;
SQL> ALTER SESSION SET TIME_ZONE = dbtimezone;
SQL> ALTER SESSION SET TIME_ZONE = '-05:00';
SQL> ALTER SESSION SET TIME_ZONE = 'Europe/London';

2). As an alternative, the operating system environment variable ORA_SDTZ can also be used to set the session time zone:
ORA_SDTZ = 'OS_TZ' | 'DB_TZ' | '[+ | -] hh:mm' | 'timezone_region'

Example:
$ ORA_SDTZ='OS_TZ'
$ export ORA_SDTZ

$ ORA_SDTZ='-05:00'
$ export ORA_SDTZ


3. How to check the database time zone ?


The DBTIMEZONE SQL function returns the value of the database time zone.

SQL> SELECT DBTIMEZONE FROM DUAL;

DBTIMEZONE
--------------
Europe/Lisbon

@ Note that the database timezone is also included in both database_properties and props$ views:
@ SQL> SELECT property_name, property_value FROM database_properties WHERE property_name='DBTIMEZONE';
@ and
@ SQL> SELECT name, value$ FROM props$ WHERE name='DBTIMEZONE';
@ Be aware that you should not rely on these views because in case of db time zone
@ change, these views reflect the new db time zone too early: they should reflect
@ it only after database shutdown and restart.


4. How to set the database time zone ?

Note that the database time zone is only relevant for TIMESTAMP WITH LOCAL TIME ZONE columns.

1). At creation time
SQL> CREATE DATABASE ...
SET TIME_ZONE='Europe/London';
If not specified with the CREATE DATABASE statement, the database time zone defaults to the server timezone offset.

2). After database creation, use the ALTER DATABASE SET TIME_ZONE statement and then shut down and restart the database.
SQL> ALTER DATABASE SET TIME_ZONE = '-05:00';
SQL> ALTER DATABASE SET TIME_ZONE = 'Europe/Lisbon';
The change will not take effect until the database is bounced.


5. How to list the valid time zone regions ?

SQL> SELECT * FROM v$timezone_names;

TZNAME TZABBREV
------------------------------ ----------
Pacific/Tahiti LMT
Poland LMT
US/Pacific PST
Europe/Zurich CET
...

The result will depend on which timezone file is currently in use. See Q&A 7-8 for further details.


6. How to retrieve the time zone offset corresponding to a time zone region ?

The new 9i TZ_OFFSET() SQL function returns the time zone offset displacement to the input time zone region.

SQL> SELECT TZ_OFFSET('Europe/London') FROM DUAL;

TZ_OFFS
-------
+01:00

The returned offset depends on the date this statement is executed.
For example, in the 'US/Pacific' time zone, it may return '-07:00' or '-08:00' whether daylight saving is in effect or not.

SQL> SELECT TZ_OFFSET(SESSIONTIMEZONE), TZ_OFFSET(DBTIMEZONE) FROM DUAL;
returns the time zone offset corresponding to the time zone set for session and database.

TZ_OFFS TZ_OFFS
------- -------
+01:00 +00:00


7. How to use a larger set of defined time zones ?

2 different time zone files contain for each zone the offset from UTC, the transition times for daylight savings and abbreviation :

- ORACLE_HOME/oracore/zoneinfo/timezone.dat
This is the default and contains the most commonly used time zones. This is the smallest file.

- ORACLE_HOME/oracore/zoneinfo/timezlrg.dat
This file contains the larger set of defined time zones and can be used if you require time zones that are not defined in the default time zone file.

To enable the use of this larger time zone data file :

1). Shutdown the database

2).1 On UNIX platforms :
set the ORA_TZFILE environment variable to the full pathname of the location for the timezlrg.dat. By default, this should be $ORACLE_HOME/oracore/zoneinfo/timezlrg.dat:

$ setenv ORA_TZFILE $ORACLE_HOME/oracore/zoneinfo/timezlrg.dat

2).2 On Windows systems :
You should add an ORA_TZFILE registry subkey for each of your Oracle Homes with the Windows Registry Editor:
Start -> Run...
Type "regedit", and click "ok"
Add or edit the following registry entry:
HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOMEID/ORA_TZFILE
where ID is the unique number identifying the Oracle home.

Set the ORA_TZFILE to the full pathname of the location for the timezlrg.dat:
By default, the value should be %ORACLE_HOME%/oracore/zoneinfo/timezlrg.dat

3). Restart the database

Once the larger timezlrg.dat is used, it must continue to be used unless the user is sure that none of the non-default zones are used for data that is stored in the database. Also, all databases that share information should use the same time zone data file.

Be aware that you can neither create nore alter these timezone definition files !


8. Which timezone-set is currently used ?

Beside checking the UNIX ORA_TZFILE parameter or the Windows registry subkey, you can easily check whether you are using the large or the default timezone file with the following query:

SQL> SELECT COUNT(*) FROM v$timezone_names;

If the default-smallest timezone region file is in use, it will return:

COUNT(*)
----------
616 (in 9.0.1.x and 9.2.x)

or

COUNT(*)
----------
1250 (in 9.0.1.x and 9.2.x)

if the largest file is in use.


9. Can customers rely on Oracle time zones ?

Timezone.dat and timezlrg.dat are based on information maintained by the U.S. Navy Observatory.

--End--

 

// 文件3: BugImageInfo.java package com.example.model; public class BugImageInfo { private String eqName; private String collectionTime; private Long monitorId; private String exhibitionPath; private String num; private String pictureUrl; private Map<String, Object> pictureAnalysis; // 改为 Map 类型 // 省略 getter/setter } package com.example.service; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.client.RestTemplate; import org.springframework.http.ResponseEntity; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.type.TypeReference; import java.util.*; import java.time.*; import java.time.format.DateTimeFormatter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; import com.example.model.BugApiResponse; import com.example.model.BugResponseData; import com.example.model.BugImageInfo; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.net.InetAddress; import java.util.stream.Collectors; import org.springframework.web.util.UriComponentsBuilder; import java.net.URI; @Service public class BugImageDownloadService { private static final ZoneId SERVER_ZONE = ZoneId.of("Asia/Shanghai"); private static final String API_URL = "http://nyzbwlw.com/situation/http/device/bug/getBugData"; private static final DateTimeFormatter API_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final DateTimeFormatter FILE_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private static final DateTimeFormatter FILE_TIME_FORMAT = DateTimeFormatter.ofPattern("HH_mm_ss"); private final ConcurrentHashMap<String, LocalDateTime> deviceLastUpdateMap = new ConcurrentHashMap<>(); @Value("${bug.download.deviceCodes:GK2025040001,GK2025040002,GK2025040003,GK2025040004,GK2025040005,GK2025040006,GK2025040007,GK2025040008}") private List<String> deviceCodes; private final Map<String, String> cookies = new ConcurrentHashMap<>(); // 存储每个设备的下一个处理日期 private final ConcurrentHashMap<String, LocalDate> deviceNextDateMap = new ConcurrentHashMap<>(); @Value("${bug.image.save.path:F:/GKD/}") private String savePath; private final RestTemplate restTemplate; private final ObjectMapper objectMapper; public BugImageDownloadService(RestTemplate restTemplate, ObjectMapper objectMapper) { this.restTemplate = restTemplate; this.objectMapper = objectMapper; } @PostConstruct public void init() { // 所有设备从固定起始日期开始 LocalDate startDate = LocalDate.of(2025, 7, 1); for (String deviceCode : deviceCodes) { deviceNextDateMap.put(deviceCode, startDate); } } /** * 持续下载所有设备的新图片 */ public void downloadNewImagesContinuously() { System.out.println("[TASK] ====== CONTINUOUS DOWNLOAD STARTED ======"); // System.out.println("[INFO] Devices: " + deviceCodes.size()); while (true) { try { boolean allDevicesUpToDate = true; // 处理每个设备的历史数据 for (String deviceCode : deviceCodes) { LocalDate currentDate = deviceNextDateMap.get(deviceCode); LocalDate today = LocalDate.now(SERVER_ZONE); if (currentDate.isBefore(today)) { allDevicesUpToDate = false; // 处理该设备当前日期的数据 LocalDateTime startOfDay = currentDate.atStartOfDay(); LocalDateTime endOfDay = currentDate.atTime(23, 59, 59); System.out.printf("[PROCESS] Device: %s | Date: %s%n", deviceCode, currentDate); // 下载该日期的图片 int[] counts = downloadImagesForDevice( deviceCode, startOfDay, endOfDay, false // 标记为历史数据请求 ); // 更新设备的下一个处理日期(明天) deviceNextDateMap.put(deviceCode, currentDate.plusDays(1)); // System.out.printf("[RESULT] Device: %s | Date: %s | Found: %d | Downloaded: %d | Failed: %d%n", // deviceCode, currentDate, counts[0], counts[1], counts[2]); // 设备间处理间隔 Thread.sleep(2000); } } // 所有设备都处理到最新日期 if (allDevicesUpToDate) { System.out.println("[STATUS] All devices up-to-date. Starting real-time updates..."); // ===== 优化后的实时更新逻辑 ===== for (String deviceCode : deviceCodes) { // 获取上次更新时间(默认当天0点) LocalDateTime lastUpdate = deviceLastUpdateMap.getOrDefault( deviceCode, LocalDate.now(SERVER_ZONE).atStartOfDay() // 使用服务器时区 ); LocalDateTime now = LocalDateTime.now(); // System.out.printf("[REALTIME] Device: %s | Time range: %s to %s%n", // deviceCode, lastUpdate, now); // 修复点1:添加第四个参数 true 表示实时请求 int[] counts = downloadImagesForDevice( deviceCode, lastUpdate, // 从上次更新时间开始 now, true // 标记为实时请求 ); // 更新最后记录时间(当前轮询结束时间) deviceLastUpdateMap.put(deviceCode, now); System.out.printf("[REALTIME-RESULT] Device: %s | Downloaded: %d | Failed: %d%n", deviceCode, counts[1], counts[2]); // 设备间处理间隔 Thread.sleep(2000); } // ======================== // 等待4h后再次检查 System.out.println("[STATUS] Real-time round completed. Waiting 4 hours..."); Thread.sleep(14_400_000); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("[ERROR] Task interrupted: " + e.getMessage()); break; } catch (Exception e) { System.err.println("[ERROR] Critical error: " + e.getMessage()); try { Thread.sleep(60_000); // 错误后等待1分钟 } catch (InterruptedException ie) { Thread.currentThread().interrupt(); break; } } } } /** * 下载指定设备在指定时间范围内的图片 */ private int[] downloadImagesForDevice(String deviceCode, LocalDateTime startTime, LocalDateTime endTime, boolean isRealtime) { int maxRetries = 3; int retryCount = 0; int waitTime = 2000; // 初始等待时间 2秒 int total = 0; int success = 0; int failed = 0; while (retryCount < maxRetries) { try { // ====== 网络诊断 ====== // ... [网络诊断代码保持不变] ... // ========== 统一时区转换逻辑 ========== ZonedDateTime serverStart = startTime.atZone(ZoneId.systemDefault()) .withZoneSameInstant(SERVER_ZONE); ZonedDateTime serverEnd = endTime.atZone(ZoneId.systemDefault()) .withZoneSameInstant(SERVER_ZONE); String startStr = serverStart.format(API_DATE_FORMAT); String endStr = serverEnd.format(API_DATE_FORMAT); // 调试日志增强 // System.out.println("[DEBUG] Time Parameters:"); // System.out.println(" Original Local: " + startTime + " - " + endTime); // System.out.println(" Converted Server: " + // serverStart.format(API_DATE_FORMAT) + " - " + // serverEnd.format(API_DATE_FORMAT)); // System.out.println(" Raw Time: " + startStr + " & " + endStr); // 使用Spring的URI构建器确保正确编码 UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(API_URL) .queryParam("deviceCode", deviceCode) .queryParam("startTime", startStr) .queryParam("endTime", endStr) .queryParam("size", 1000) .queryParam("t", System.currentTimeMillis()); String apiUrl = builder.build().toUriString(); // ============================ // System.out.println("[DEBUG] Final request URL: " + apiUrl); // ====== 创建带Cookie的请求头 ====== HttpHeaders headers = new HttpHeaders(); // 添加浏览器级 User-Agent headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0"); // 必须添加的请求头 headers.set("Accept", "application/json, text/plain, */*"); headers.set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"); headers.set("Connection", "keep-alive"); headers.set("Referer", "http://nyzbwlw.com/situation/"); // 关键修复:添加 Referer headers.set("Origin", "http://nyzbwlw.com"); headers.set("Sec-Fetch-Dest", "empty"); headers.set("Sec-Fetch-Mode", "cors"); headers.set("Sec-Fetch-Site", "same-origin"); // 添加 Cookie(关键修复:使用持久化 Cookie) if (!cookies.isEmpty()) { String cookieHeader = cookies.entrySet().stream() .map(entry -> entry.getKey() + "=" + entry.getValue()) .collect(Collectors.joining("; ")); headers.add("Cookie", cookieHeader); // System.out.println("[DEBUG] Sending cookies: " + cookieHeader); } // 发送请求 ResponseEntity<String> response = restTemplate.exchange( apiUrl, HttpMethod.GET, new HttpEntity<>(headers), String.class); // 保存新Cookie List<String> setCookieHeaders = response.getHeaders().get("Set-Cookie"); if (setCookieHeaders != null) { for (String cookie : setCookieHeaders) { // 提取关键 Cookie(排除过期/路径信息) String[] cookieParts = cookie.split(";")[0].split("="); if (cookieParts.length >= 2) { String cookieName = cookieParts[0].trim(); String cookieValue = cookieParts[1].trim(); cookies.put(cookieName, cookieValue); // System.out.println("[COOKIE] Saved session cookie: " + cookieName); } } } // 响应状态日志 // System.out.println("[DEBUG] Response Status: " + // response.getStatusCodeValue() + " " + // response.getStatusCode().getReasonPhrase()); if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { String responseBody = response.getBody(); System.out.println("[RESPONSE-DATA] " + responseBody); // System.out.println("[DEBUG] Raw API response snippet: " // + responseBody.substring(0, Math.min(300, responseBody.length())) // + (responseBody.length() > 300 ? "..." : "")); // 使用POJO解析响应 BugApiResponse apiResponse = objectMapper.readValue(responseBody, BugApiResponse.class); // System.out.printf("[DEBUG] Parsed API response code: %d | message: %s%n", // apiResponse.getCode(), apiResponse.getMsg()); if (apiResponse.getCode() == 100) { BugResponseData data = apiResponse.getData(); List<BugImageInfo> bugList = (data != null && data.getList() != null) ? data.getList() : Collections.emptyList(); total = bugList.size(); // System.out.printf("[DEBUG] Found %d valid image entries%n", total); // 如果有数据,处理并返回 if (total > 0) { for (BugImageInfo bug : bugList) { String pictureUrl = bug.getPictureUrl(); String collectionTime = bug.getCollectionTime(); if (pictureUrl != null && !pictureUrl.isEmpty() && collectionTime != null && !collectionTime.isEmpty()) { System.out.printf("[PROCESSUrl] Downloading: %s | %s%n", collectionTime, pictureUrl); if (downloadImage(deviceCode, pictureUrl, collectionTime)) { success++; } else { failed++; } } else { // System.err.printf("[WARN] Invalid data: URL=%s | Time=%s%n", // pictureUrl, collectionTime); failed++; } } return new int[]{total, success, failed}; } } else { System.err.println("[API-ERROR] Device: " + deviceCode + " | Code: " + apiResponse.getCode()); } } } catch (Exception e) { System.err.println("[DOWNLOAD-ERROR] Device: " + deviceCode); // e.printStackTrace(); } // 如果没有数据或出错,等待后重试 retryCount++; if (retryCount < maxRetries) { try { System.out.printf("[RETRY] Retrying in %d ms (attempt %d/%d)%n", waitTime, retryCount + 1, maxRetries); Thread.sleep(waitTime); waitTime *= 2; // 指数退避 } catch (InterruptedException ie) { Thread.currentThread().interrupt(); break; } } } System.out.printf("[STATS] Device: %s | Total: %d | Success: %d | Failed: %d%n", deviceCode, total, success, failed); return new int[]{total, success, failed}; } private boolean downloadImage(String deviceCode, String imageUrl, String collectionTime) { try { // 解析采集时间 LocalDateTime dateTime = LocalDateTime.parse(collectionTime, API_DATE_FORMAT); // 创建保存路径 Path saveDir = Paths.get(savePath, deviceCode, dateTime.format(FILE_DATE_FORMAT)); // 确保目录存在 if (!Files.exists(saveDir)) { Files.createDirectories(saveDir); System.out.println("[DIR] Created directory: " + saveDir); } // 生成文件名 String fileName = dateTime.format(FILE_TIME_FORMAT) + ".png"; Path filePath = saveDir.resolve(fileName); // 跳过已存在文件 if (Files.exists(filePath)) { System.out.println("[SKIP] File already exists: " + filePath); return true; } // 下载图片 System.out.println("[DOWNLOAD] Fetching: " + imageUrl); byte[] imageBytes = restTemplate.getForObject(imageUrl, byte[].class); // 验证图片数据 if (imageBytes == null || imageBytes.length == 0) { System.err.println("[ERROR] Empty image data: " + imageUrl); return false; } // 保存图片 Files.write(filePath, imageBytes); System.out.println("[SUCCESS] Saved: " + filePath + " (" + imageBytes.length + " bytes)"); return true; } catch (Exception e) { // 详细错误日志 System.err.println("[IMAGE-ERROR] URL: " + imageUrl); System.err.println(" Collection Time: " + collectionTime); System.err.println(" Device: " + deviceCode); System.err.println(" Error Details: " + e.getMessage()); e.printStackTrace(); // 打印完整堆栈 return false; } } }依据上述代码解决报错:[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project example-project: Compilation failure: Compilation failure: [ERROR] /D:/biancheng/rjxm/zxgxspringboot/src/main/java/com/example/model/BugImageInfo.java:[11,13] 找不到符号 [ERROR] 符号: 类 Map [ERROR] 位置: 类 com.example.model.BugImageInfo [ERROR] /D:/biancheng/rjxm/zxgxspringboot/src/main/java/com/example/service/BugImageDownloadService.java:[283,52] 找不到符号 [ERROR] 符号: 方法 getPictureUrl() [ERROR] 位置: 类型为com.example.model.BugImageInfo的变量 bug [ERROR] /D:/biancheng/rjxm/zxgxspringboot/src/main/java/com/example/service/BugImageDownloadService.java:[284,56] 找不到符号 [ERROR] 符号: 方法 getCollectionTime() [ERROR] 位置: 类型为com.example.model.BugImageInfo的变量 bug [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
最新发布
08-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值