[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H0GQ0DSAFHNJAWM99HXM8P":3,"skill-same:01M6H0GQ0DSAFHNJAWM99HXM8P":87},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":24,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":53,"repositoryHtmlUrl":54,"repositoryHomepageUrl":6,"ownerHtmlUrl":55,"ownerBlogUrl":56,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M6H0GQ0DSAFHNJAWM99HXM8P","store-instants-as-utc",null,"Use when a timestamp is written to a database, log line or API payload — persist the instant in UTC with an explicit offset, never a bare local wall-clock string.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-store-instants-as-utc\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-store-instants-as-utc\u002FSKILL.md",[19],{"categoryNo":20,"categoryName":21,"taxonomyType":22,"taxonomyTypeDesc":23},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"store instants as utc","store","as","line","when","bare","persist","wall","with","clock","STRING","database","local","log","payload","never","use","timestamp","instant","api","2026-11-10 10:12:30",false,"---\nname: store-instants-as-utc\ndescription: Use when a timestamp is written to a database, log line or API payload — persist the instant in UTC with an explicit offset, never a bare local wall-clock string.\n---\n\n# Store instants as UTC\n\nAn instant is a point on the world timeline; a wall-clock reading is not. A UTC (or offset-bearing) value lets two hosts, two timezones and two DST regimes agree about what happened and in what order.\n\n## Procedure\n\n1. Declare the column type, not just the value. In Postgres use `TIMESTAMPTZ`; a plain `TIMESTAMP` silently drops the offset:\n```\nALTER TABLE events ALTER COLUMN created_at TYPE timestamptz USING created_at AT TIME ZONE 'UTC';\n```\n2. Serialize as ISO-8601 with an offset. `2026-03-01T14:00:00Z`, never `2026-03-01 14:00:00`:\n```\ndate -u +%Y-%m-%dT%H:%M:%SZ\n```\n3. In the application layer, produce aware objects and convert only when formatting:\n```python\nfrom datetime import datetime, timezone\nnow = datetime.now(timezone.utc)            # aware, UTC\nrow = now.isoformat().replace(\"+00:00\", \"Z\")  # 2026-03-01T14:00:00Z\n```\n4. Store the original zone name separately if you ever need to redisplay in the user's local time — UTC loses it. Keep `created_at timestamptz` plus `created_tz text` (`'America\u002FNew_York'`).\n5. Reject writes that carry no offset at the API boundary. A regex gate on ingress:\n```\nrg -n '\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(?!Z|[+-]\\d{2}:?\\d{2})' payloads\u002F   # finds bare local stamps\n```\n6. Migrate legacy local strings by pinning the zone they were written in, not by assuming UTC:\n```\nUPDATE events SET created_at = created_at AT TIME ZONE 'America\u002FNew_York' WHERE created_at_was_local;\n```\n7. Verify round-trip: write an instant, read it back, and confirm the offset survives.\n\n## Pitfalls\n\n- `--` A naive `TIMESTAMP` column read by a driver set to a different `TimeZone` returns a different wall clock for the same row. The bug looks like \"the date changed\" with no code change.\n- `new Date(\"2026-03-01\")` in JavaScript parses date-only as UTC midnight; `new Date(\"2026-03-01T00:00\")` parses as local. Two spellings, two instants.\n- Emitting UTC but truncating the `Z` produces a string that a downstream parser reads as local. Keep the offset suffix.\n- Sorting a mixed column of `Z` and `+05:00` strings lexically reorders events across zones; sort parsed instants, not text.\n\n## Verification\n\n```\npsql -c \"SELECT count(*) FROM events WHERE created_at IS NOT NULL AND pg_typeof(created_at)::text \u003C> 'timestamp with time zone';\"\n```\nReturns `0` = every stored timestamp is offset-aware. Report: \"events.created_at is timestamptz, 0 naive rows; API rejects offset-less strings.\"\n","# Store instants as UTC\n\nAn instant is a point on the world timeline; a wall-clock reading is not. A UTC (or offset-bearing) value lets two hosts, two timezones and two DST regimes agree about what happened and in what order.\n\n## Procedure\n\n1. Declare the column type, not just the value. In Postgres use `TIMESTAMPTZ`; a plain `TIMESTAMP` silently drops the offset:\n```\nALTER TABLE events ALTER COLUMN created_at TYPE timestamptz USING created_at AT TIME ZONE 'UTC';\n```\n2. Serialize as ISO-8601 with an offset. `2026-03-01T14:00:00Z`, never `2026-03-01 14:00:00`:\n```\ndate -u +%Y-%m-%dT%H:%M:%SZ\n```\n3. In the application layer, produce aware objects and convert only when formatting:\n```python\nfrom datetime import datetime, timezone\nnow = datetime.now(timezone.utc)            # aware, UTC\nrow = now.isoformat().replace(\"+00:00\", \"Z\")  # 2026-03-01T14:00:00Z\n```\n4. Store the original zone name separately if you ever need to redisplay in the user's local time — UTC loses it. Keep `created_at timestamptz` plus `created_tz text` (`'America\u002FNew_York'`).\n5. Reject writes that carry no offset at the API boundary. A regex gate on ingress:\n```\nrg -n '\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(?!Z|[+-]\\d{2}:?\\d{2})' payloads\u002F   # finds bare local stamps\n```\n6. Migrate legacy local strings by pinning the zone they were written in, not by assuming UTC:\n```\nUPDATE events SET created_at = created_at AT TIME ZONE 'America\u002FNew_York' WHERE created_at_was_local;\n```\n7. Verify round-trip: write an instant, read it back, and confirm the offset survives.\n\n## Pitfalls\n\n- `--` A naive `TIMESTAMP` column read by a driver set to a different `TimeZone` returns a different wall clock for the same row. The bug looks like \"the date changed\" with no code change.\n- `new Date(\"2026-03-01\")` in JavaScript parses date-only as UTC midnight; `new Date(\"2026-03-01T00:00\")` parses as local. Two spellings, two instants.\n- Emitting UTC but truncating the `Z` produces a string that a downstream parser reads as local. Keep the offset suffix.\n- Sorting a mixed column of `Z` and `+05:00` strings lexically reorders events across zones; sort parsed instants, not text.\n\n## Verification\n\n```\npsql -c \"SELECT count(*) FROM events WHERE created_at IS NOT NULL AND pg_typeof(created_at)::text \u003C> 'timestamp with time zone';\"\n```\nReturns `0` = every stored timestamp is offset-aware. Report: \"events.created_at is timestamptz, 0 naive rows; API rejects offset-less strings.\"\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-store-instants-as-utc",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-14 02:27:51",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill store-instants-as-utc",{"tool":65,"command":66},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill store-instants-as-utc",{"tool":68,"command":69},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill store-instants-as-utc","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-store-instants-as-utc\u002FSKILL.md",true,[73,77,83],{"path":74,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":76,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":78,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":81,"sourceHtmlUrl":82},"SOURCE.md","REFERENCE","参考文档",347,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-store-instants-as-utc\u002FSOURCE.md",{"path":84,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":85,"sourceHtmlUrl":86},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-store-instants-as-utc\u002FTRUST.auto.yaml",[88,116,138,156,169,179],{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":92,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":45},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":120,"licenseFileUrl":121,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":45},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[125,126,127,44,128,129,130,131,132,133,134,135,136,137],"mexc spot websocket","spot","websocket","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":120,"licenseFileUrl":142,"sourceHtmlUrl":143,"categories":144,"keywords":145,"publishedAt":45},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[146,126,147,148,149,150,151,135,134,133,152,153,154,129,155,128,44],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":120,"licenseFileUrl":160,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":45},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[164,165,127,166,167,136,134,168,132,131,129,128],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":170,"name":171,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":172,"sourceHtmlUrl":173,"categories":174,"keywords":175,"publishedAt":45},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[176,177,178],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":180,"name":181,"nameZh":6,"description":182,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":183,"sourceHtmlUrl":184,"categories":185,"keywords":186,"publishedAt":45},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[187,188,189,190,191,192,193,41,194,195,196],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]