From f8bb2871947c46c577964e8da49d7e5b32b9f7d2 Mon Sep 17 00:00:00 2001 From: vgearen Date: Fri, 3 Apr 2026 14:14:49 +0800 Subject: [PATCH] v1.2.6: Hide daily PnL on non-trading days (holidays/weekends) - Add Quote.isToday: compare updateTime date with today in Beijing timezone - effectiveDailyPnl returns nil when quote data is stale (not from today) - Prevents showing yesterday's change as today's daily PnL on closed markets Co-Authored-By: Claude Opus 4.6 (1M context) --- StockMonitor.xcodeproj/project.pbxproj | 460 ------------------------- StockMonitor/Models/Quote.swift | 13 + StockMonitor/State/AppState.swift | 2 + 3 files changed, 15 insertions(+), 460 deletions(-) diff --git a/StockMonitor.xcodeproj/project.pbxproj b/StockMonitor.xcodeproj/project.pbxproj index 769d9f3..e69de29 100644 --- a/StockMonitor.xcodeproj/project.pbxproj +++ b/StockMonitor.xcodeproj/project.pbxproj @@ -1,460 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 77; - objects = { - -/* Begin PBXContainerItemProxy section */ - 9FBAD6D52F67B45500F2B1E3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9FBAD6B72F67B3E800F2B1E3 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 9FBAD6BE2F67B3E800F2B1E3; - remoteInfo = Stockbar; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 9FBAD6BF2F67B3E800F2B1E3 /* Stockbar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stockbar.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 9FBAD6D12F67B45500F2B1E3 /* StockbarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StockbarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFileSystemSynchronizedRootGroup section */ - 9FBAD6C12F67B3E800F2B1E3 /* StockMonitor */ = { - isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - ); - path = StockMonitor; - sourceTree = ""; - }; - 9FBAD6D22F67B45500F2B1E3 /* StockMonitorTests */ = { - isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - ); - path = StockMonitorTests; - sourceTree = ""; - }; -/* End PBXFileSystemSynchronizedRootGroup section */ - -/* Begin PBXFrameworksBuildPhase section */ - 9FBAD6BC2F67B3E800F2B1E3 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9FBAD6CE2F67B45500F2B1E3 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9FBAD6B62F67B3E800F2B1E3 = { - isa = PBXGroup; - children = ( - 9FBAD6C12F67B3E800F2B1E3 /* StockMonitor */, - 9FBAD6D22F67B45500F2B1E3 /* StockMonitorTests */, - 9FBAD6C02F67B3E800F2B1E3 /* Products */, - ); - sourceTree = ""; - }; - 9FBAD6C02F67B3E800F2B1E3 /* Products */ = { - isa = PBXGroup; - children = ( - 9FBAD6BF2F67B3E800F2B1E3 /* Stockbar.app */, - 9FBAD6D12F67B45500F2B1E3 /* StockbarTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 9FBAD6BE2F67B3E800F2B1E3 /* Stockbar */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9FBAD6CA2F67B3E900F2B1E3 /* Build configuration list for PBXNativeTarget "Stockbar" */; - buildPhases = ( - 9FBAD6BB2F67B3E800F2B1E3 /* Sources */, - 9FBAD6BC2F67B3E800F2B1E3 /* Frameworks */, - 9FBAD6BD2F67B3E800F2B1E3 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - fileSystemSynchronizedGroups = ( - 9FBAD6C12F67B3E800F2B1E3 /* StockMonitor */, - ); - name = Stockbar; - productName = Stockbar; - productReference = 9FBAD6BF2F67B3E800F2B1E3 /* Stockbar.app */; - productType = "com.apple.product-type.application"; - }; - 9FBAD6D02F67B45500F2B1E3 /* StockbarTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9FBAD6D72F67B45500F2B1E3 /* Build configuration list for PBXNativeTarget "StockbarTests" */; - buildPhases = ( - 9FBAD6CD2F67B45500F2B1E3 /* Sources */, - 9FBAD6CE2F67B45500F2B1E3 /* Frameworks */, - 9FBAD6CF2F67B45500F2B1E3 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 9FBAD6D62F67B45500F2B1E3 /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - 9FBAD6D22F67B45500F2B1E3 /* StockMonitorTests */, - ); - name = StockbarTests; - productName = StockbarTests; - productReference = 9FBAD6D12F67B45500F2B1E3 /* StockbarTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 9FBAD6B72F67B3E800F2B1E3 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 2630; - LastUpgradeCheck = 2630; - TargetAttributes = { - 9FBAD6BE2F67B3E800F2B1E3 = { - CreatedOnToolsVersion = 26.3; - }; - 9FBAD6D02F67B45500F2B1E3 = { - CreatedOnToolsVersion = 26.3; - TestTargetID = 9FBAD6BE2F67B3E800F2B1E3; - }; - }; - }; - buildConfigurationList = 9FBAD6BA2F67B3E800F2B1E3 /* Build configuration list for PBXProject "StockMonitor" */; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 9FBAD6B62F67B3E800F2B1E3; - minimizedProjectReferenceProxies = 1; - preferredProjectObjectVersion = 77; - productRefGroup = 9FBAD6C02F67B3E800F2B1E3 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 9FBAD6BE2F67B3E800F2B1E3 /* Stockbar */, - 9FBAD6D02F67B45500F2B1E3 /* StockbarTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 9FBAD6BD2F67B3E800F2B1E3 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9FBAD6CF2F67B45500F2B1E3 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 9FBAD6BB2F67B3E800F2B1E3 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9FBAD6CD2F67B45500F2B1E3 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 9FBAD6D62F67B45500F2B1E3 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 9FBAD6BE2F67B3E800F2B1E3 /* Stockbar */; - targetProxy = 9FBAD6D52F67B45500F2B1E3 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 9FBAD6C82F67B3E900F2B1E3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 13.5; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 9FBAD6C92F67B3E900F2B1E3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 13.5; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - }; - name = Release; - }; - 9FBAD6CB2F67B3E900F2B1E3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = StockMonitor/StockMonitor.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - ENABLE_APP_SANDBOX = NO; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SELECTED_FILES = readonly; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_CFBundleDisplayName = Stockbar; - INFOPLIST_KEY_LSUIElement = YES; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = 1.2.5; - PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.Stockbar; - PRODUCT_NAME = "$(TARGET_NAME)"; - REGISTER_APP_GROUPS = YES; - STRING_CATALOG_GENERATE_SYMBOLS = YES; - SWIFT_APPROACHABLE_CONCURRENCY = YES; - SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 9FBAD6CC2F67B3E900F2B1E3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = StockMonitor/StockMonitor.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - ENABLE_APP_SANDBOX = NO; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SELECTED_FILES = readonly; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_CFBundleDisplayName = Stockbar; - INFOPLIST_KEY_LSUIElement = YES; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 13.5; - MARKETING_VERSION = 1.2.5; - PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.Stockbar; - PRODUCT_NAME = "$(TARGET_NAME)"; - REGISTER_APP_GROUPS = YES; - STRING_CATALOG_GENERATE_SYMBOLS = YES; - SWIFT_APPROACHABLE_CONCURRENCY = YES; - SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 9FBAD6D82F67B45500F2B1E3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.2.5; - PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.StockbarTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - STRING_CATALOG_GENERATE_SYMBOLS = NO; - SWIFT_APPROACHABLE_CONCURRENCY = YES; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stockbar.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Stockbar"; - }; - name = Debug; - }; - 9FBAD6D92F67B45500F2B1E3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.2.5; - PRODUCT_BUNDLE_IDENTIFIER = com.vgearen.StockbarTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - STRING_CATALOG_GENERATE_SYMBOLS = NO; - SWIFT_APPROACHABLE_CONCURRENCY = YES; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stockbar.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Stockbar"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 9FBAD6BA2F67B3E800F2B1E3 /* Build configuration list for PBXProject "StockMonitor" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9FBAD6C82F67B3E900F2B1E3 /* Debug */, - 9FBAD6C92F67B3E900F2B1E3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9FBAD6CA2F67B3E900F2B1E3 /* Build configuration list for PBXNativeTarget "Stockbar" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9FBAD6CB2F67B3E900F2B1E3 /* Debug */, - 9FBAD6CC2F67B3E900F2B1E3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9FBAD6D72F67B45500F2B1E3 /* Build configuration list for PBXNativeTarget "StockbarTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9FBAD6D82F67B45500F2B1E3 /* Debug */, - 9FBAD6D92F67B45500F2B1E3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 9FBAD6B72F67B3E800F2B1E3 /* Project object */; -} diff --git a/StockMonitor/Models/Quote.swift b/StockMonitor/Models/Quote.swift index 7288b61..c7c290e 100644 --- a/StockMonitor/Models/Quote.swift +++ b/StockMonitor/Models/Quote.swift @@ -32,6 +32,19 @@ struct Quote { var isUp: Bool { change > 0 } var isDown: Bool { change < 0 } + /// 数据是否为今天(通过 updateTime 中的日期判断) + var isToday: Bool { + // 匹配 yyyy-MM-dd 或 yyyy/MM/dd 格式 + let digits = updateTime.replacingOccurrences(of: "/", with: "-") + guard digits.count >= 10 else { return false } + let dateStr = String(digits.prefix(10)) + let fmt = DateFormatter() + fmt.dateFormat = "yyyy-MM-dd" + fmt.timeZone = TimeZone(identifier: "Asia/Shanghai") + let today = fmt.string(from: Date()) + return dateStr == today + } + var formattedPercent: String { let sign = changePercent >= 0 ? "+" : "" return String(format: "\(sign)%.2f%%", changePercent) diff --git a/StockMonitor/State/AppState.swift b/StockMonitor/State/AppState.swift index ec022a3..03b02a9 100644 --- a/StockMonitor/State/AppState.swift +++ b/StockMonitor/State/AppState.swift @@ -260,6 +260,8 @@ final class AppState: ObservableObject { func effectiveDailyPnl(stock: Stock, quote: Quote) -> Double? { guard let shares = effectiveShares(for: stock) else { return nil } + // 休市日数据是昨天的,不显示日盈亏 + guard quote.isToday else { return nil } return quote.change * shares }