数ヶ月遅れてパーティーに参加してすみません...
これらの回答の問題は、これがBUGであることを実際に明らかにしていないことです。または、より正確に言えば、これは Google が「正しい」動作であると判断したものです (Issue 1271を参照してください。たとえば、アクションなしで閉じられました)。
このことを考慮。誰かの生年月日をスプレッドシートに入れたいのですが、それらのリストがたくさんあります。次に、値を読み取り、フォームに入れたいと思います。
function getAge(ss, index) {
var ages = ss.getRangeByName("birthDates").getValues();
return ages[index];
}
...
app.createLabel(getAge(ss, index));
フォームには、4 月から 10 月の間に生まれたすべての人の生年月日が間違って含まれるようになりました。Google は、彼らが実際には 1 日早く生まれたと判断しました。または、年齢を読み取って、処理せずに別のスプレッドシートに入力してみてください。両方のスプレッドシートのタイムゾーン設定は同じです。同じ話で、生年月日が間違っているとメールで言われると、本当にバカに見えてしまいます。
これがどのように行われるべきか: 誰かが日付を手動で指定した場合、たとえば "06/06/1997" を使用してその日付を読み取るとgetValue
、前日ではなく "06/06/1997" が返されることを期待します。彼らはあなたが彼らを推測しようとすることを本当に期待してgetValue
いません: 1時間前に渡しますか?」
それはクレイジーです。もしエクセルがそんなことをしたら、笑いものになるでしょう。直してください。
編集
Serge、それは非常に興味深いですが、あなたのスプレッドシートは TZ を抽出し、その TZ に従って表示する回避策を示しています。しかし、これはそもそも間違っているという問題を回避するだけです。このことを考慮。スプレッドシートには、ほとんどの場合、決まった日付の記念日が含まれています - 誰かの誕生日、戦いの日、予定の日時など。これらはTZ とは独立しています。. 誕生日がベルギーで 1960 年 7 月 6 日である場合、カリフォルニアに住んでいる場合は 7 月 6 日でもあります。午前 0 時 30 分に生まれた場合、CET と PDT で実際には 7 月 5 日だったとしても、パスポートには 7 月 6 日と表示されます。記念日や予定の場合、誰もタイムゾーンを気にしません。スプレッドシートでは、TZ を気にするユーザーはごくわずかです。それが実際に重要な単一のユースケースをすぐに思いつくことはできません。
Lotus 1-2-3 はこれを正しく理解しました。Excelはこれを正しく理解しました。日付は整数のシリアル番号で、タイム ゾーン情報はありません。あるスプレッドシートから別のスプレッドシートに日付をコピーすると、常に正しい結果が得られます。VB などを使用してスプレッドシートから日付を取得し、それを別のスプレッドシートに入れます。それは常に正しいと思います (私はそう思います)。言いたくないことですが、Excel はスプレッドシートを定義します。VBとは別に。
GAS で を使用して日付をコピーするとgetValues
、 が間違っています。グーグルはこれを過度に賢くしました。入力した日付が実際には UTC を基準としたエポック日付であると仮定して、スプレッドシートが作成された TZ を見つけ、スプレッドシートの現在の TZ 設定 (少なくとも、私はそれがあなたがしていることだと思います)。しかし、だから何?そして、それは常に機能しますか?スプレッドシートを PDT に住んでいる人に郵送するとどうなりますか? あなたはそれを機能させることができると確信していますが、それは要点を逃しています.これは単なる回避策であり、壊れやすいと思います.スクリプト設定、およびそれらすべてを考慮する必要があります- ahab' を参照してください)。根本的な問題は、Google スプレッドシートが特定の TZ を基準にして日付を保存することです (基になるフォーマット ms は Unix エポックを基準にしていますか??)。これは単に間違っていたものであり、現在では修正できず、日付の処理に関する大量のワームの一部にすぎません。
短期的な修正として、おそらくスプレッドシートのすべての日付に 12 時間を追加できます。長期的な修正として、おそらくすべての日付をテキスト文字列として処理し、JavaScript で自分で処理する必要があります。GAS 日付の失われたミリ秒に関係する問題を処理するために、すべての経過時間を「整数」のミリ秒に置き換える必要がありました。続けて、私が間違っていると納得させてください。
Sergeによる編集:
こんにちは、読みやすくするために編集で自由に答えさせていただきました(申し訳ありません)。
私はあなたの意見を理解していますが、私はそれを共有しません.
あなたが参照しているUIの例は、スプレッドシートの日付ではなく、純粋なjavascriptであるため、実際に回避策が必要です...とはいえ、ExcelスプレッドシートとGoogleスプレッドシートは同じように機能します(翌日はday + 1、time = decimals、ref date 0 = 12/31/1899)) スプレッドシートの世界にとどまっている限り、スプレッドシートを終了して Javascript に移動すると問題が発生します (参照日 = 01/01/1970、ミリ秒単位でカウント)...
彼らが TZ を気にせず、どのタイム ゾーンでも日付を「静的」に保つことを選択していた場合、他の多くの問題が発生していたでしょう。たとえば、ベルギーの私とワシントンのオバマ大統領の間でスカイプの予定を設定したい場合はどうなるでしょうか。 ? その会話を月曜日の午前 8 時に行うことにした場合、ベルギーまたはワシントンでは午前 8 時になりますか?
Google ソリューションを使用すると、彼は少し早く起きる必要がありますが、日付と時刻が同じ「瞬間」を示すため、私たちは両方ともそこにいます。あなたが示唆する方法では、お互いに話す機会はありません。 (なんて悲しいことでしょう^^) .
明らかにより良い選択である状況は他にもたくさんあります。Calendar サービスとの通信も良い例です。
このようなドキュメントは同じ方法で共有されず、日付を Javascript 日付オブジェクトに変換しないため、静的な Excel ソリューションはうまく機能します。Excel SS はコンピュータのユーザーに関連付けられています。Google SS は、タイム ゾーン設定を使用してユーザーのコンピュータとの関係を維持します。これは、(本質的に) ユーザーのコンピュータに関連付けられていないためです。私はあなたを納得させる望みはほとんどありません (;-) ですが、これで少なくとも少しは明確になることを願っています... (とにかく私は Google のエンジニアではないので、Google に影響を与える方法はまったくありません ^^)。
もう1つ編集...
これは、TZ 設定が GMT-8 に設定された小さなテスト シートです。このテスト シートは、他のテスト シート (ベルギーの冬時間 GMT+2 に設定)の値を取得し、この単純なスクリプトを使用して正しい方法で表示します。
function timeCorrection() {
var thisSheet = SpreadsheetApp.getActiveSheet();
var otherSS = SpreadsheetApp.openById('0AnqSFd3iikE3dENrc2h1M0ktQTlSNWpNUi1TS0lrNlE');
var otherSheet = otherSS.getSheetByName('Sheet1');
var otherValue = otherSheet.getRange(1,1).getValue();
var tz = otherSS.getSpreadsheetTimeZone();
var thisSheetValue = new Date(Utilities.formatDate(otherValue,tz,'MM/dd/yyyy HH:mm:ss'));
thisSheet.getRange(1,1).setValue(thisSheetValue);
}
それと同じくらい簡単です;-)、「外国のシート」の設定は、バンクーバーで作成された新しく作成されたシートのデフォルトであるスクリプト設定と同じ値に設定されます。