Excel VBA、500 486 485 470バイト
匿名VBEイミディエイトウィンドウ関数
年から[A1]
、月から[B1]
、日から[C1]
、時間から[D1]
、分から[E1]
、秒、[F1]
およびオプションの追加の精度配列として入力を受け取る匿名VBEイミディエイトウィンドウ関数は[G1:Z1]
、RFC2550タイムスタンプを計算し、VBEイミディエイトウィンドウに出力します。以下で宣言されたヘルパー関数を使用します。
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:Z1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
ヘルパー機能
ベース26の数字は、そのことを入力番号とリターンを取る宣言ヘルパー関数1->A
と26->Z
パブリックモジュールに配置する必要があります。
Function b(n)
While n
n=n-1
d=n Mod 26+1
n=Int(n/26)
d=d+26*(d<0):n=n-(d<0)
b=Chr(64+d)+b
Wend
End Function
使用法
明確なモジュールに使用されなければならない、またはモジュールはVARSとして、実行前にクリアしなければならないj
、o
とp
のコードの実行の開始時にデフォルト、初期化されていない状態であると想定されています。以下のためj
である、Variant\Integer
変数は、このデフォルト値がある0
とのためo
とp
されている、Variant\String
変数、このデフォルト値は空の文字列です(""
)。
文字列の配列である入力1:1
はActiveSheet から取得され、出力はVBEイミディエイトウィンドウに送信されます。
サンプルI / O
[A1:F1]=Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711021028
Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1:H1]=Array("-696443266","1","3","6","10","15","21","28")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
*V3035567330103061015021028
Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1]="45941"
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
A45941
Cells.Clear:j=0:o="":p="" '' clear the worksheet and vars
[A1:F1]=Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
n=Left([A1],1)="-":y=Mid([A1],1-n):l=Len(y):o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y):For Each c In[B1:ZZ1]:j=j+1:p=p+IIf(c,Format(c,IIf(j>5,"000","00")),""):Next:If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:?IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))Replace(o,"=","!")p:Else?o;p
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711
Sub
ルーチンバージョン
年から[A1]
、月から[B1]
、日から[C1]
、時間から[D1]
、分から[E1]
、秒、[F1]
およびオプションの追加の精度配列として入力を受け取る宣言されたサブルーチンは[G1:Z1]
、RFC2550タイムスタンプを計算し、VBEイミディエイトウィンドウに出力します。
Sub R(x)
a=x(0)
n=Left(a,1)="-"'<- that `"` is only there to make sure highlighting is correct
y=Mid(a,1-n)
l=Len(y)
o=IIf(l<5,Right("000"&y,4),IIf(l<31,"",String(Len(b(l-30)),94))&B(l-IIf(l<31,4,30))&y)
If n Then For i=1To Len(o):c=Asc(Mid(o,i,1)):Mid$(o,i,1)=Chr(IIf(c<60,105,155)-c):Next:o=IIf(l<5,"/",IIf(InStr(1,o,"="),"","*"))&Replace(o,"=","!")
For j=1To UBound(x)
o=o+IIf(x(j),Format(x(j),IIf(j>5,"000","00")),"")
Next
[A2]=o
End Sub
Function b(n)
While n
n=n-1
d=n Mod 26+1
n=Int(n/26)
d=d+26*(d<0):n=n-(d<0)
b=Chr(64+d)+b
Wend
End Function
使用法
範囲への入力は、[A1:ZZ1]
必要に応じて手動で、セルに左から右へ入力するか、VBEイミディエイトウィンドウから割り当てることができます。
注目すべきは、Excelが数値を科学表記法に自動変換するため、セルをテキストセルに設定するか、12桁以上の基数10の数値をテキストとしてセルに明示的に挿入するか、'
セルの値の先頭にリテラルを追加することにより
サンプルI / O
r Split("4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11",".")
?[A2] '' <- print output to VBE console
^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711 '' <- Output
r Array("47883552573911529811831375872990","1","1","2","3","5","8","13")
?[A2]
^B478835525739115298118313758729900101020305008013
r Array("-696443266","1","3","6","10","15","21","28")
?[A2]
*V3035567330103061015021028
r Array("45941")
?[A2]
A45941
ゴルフをしていないと説明
'' Returns RFC2550 timestamp corresponding to passed vars
Public Function RFC2550(ByVal pYear As String, ParamArray Extra() As Variant) As String
'' Declare Vars
Dim Negative As Boolean, _
leny As Long, _
i As Long, _
c As Byte, _
s As Variant, _
out As String
'' Check if year is negative and store the absolute value of the year
Let Negative = Left(pYear, 1) = "-"
Let pYear = Mid(pYear, 1 - Negative)
'' Take the length of the year
Let leny = Len(pYear)
If leny < 5 Then
'' If the length is less than 5, pad the year left to 4 characters
'' using zeros
Let out = Format("0000", pYear)
Else
'' If the length of the year is greater than 30, then set out to be
'' as string comprised of length-30 instances of `^`
Let out = IIf(leny < 31, "", String(Len(Base26(leny - 30)), 94))
'' append the Base26 representation of the length of the year,
'' minus 30, if the length is greater than 30
Let out = out & Base26(leny - IIf(leny < 31, 4, 30))
'' append the year to out
Let out = out & pYear
End If
If Negative Then
'' iterate across out
For i = 1 To Len(out)
'' store the char code for the current char
Let c = Asc(Mid(out, i, 1))
'' swap letter/number with its inverse (0->9,A->Z)
Mid$(out, i, 1) = Chr(IIf(c < 60, 105, 155) - c)
Next i
'' replace `=` (the inverse of `^`) with `!`
Let out = Replace(out, "=", "!")
'' Prepend either `/`, `*`, or nothing depending on length and
'' start of out
Let out = IIf(leny < 5, "/", IIf(InStr(1, out, "!"), "", "*")) & out
End If
Let i = 1
For Each s In Extra
'' append all of the extra precision data - padding to 2 chars for
'' the first 5 elements in the array (month, day, hour, minute and
'' second) and to 3 chars for all following elements (milli, micro,
'' nano, pico, femto, atto, zepto, yocto - seconds) with the char 0
Let out = out & IIf(s, Format(s, IIf(i > 5, "000", "00")), "")
Let i = i + 1
Next
'' return out
Let RFC2550 = out
End Function
'' returns non-standard base26 version of input number
'' 1->A, 2->B,... 26->Z
Function Base26(ByVal n As Long) As String
'' declare vars
Dim out As String, _
digit As Integer
'' init out, digit
Let out = ""
Let digit = 0
'' iterate through n
While n
'' Decrement, hold the value of the digit
Let n = n - 1
Let digit = n Mod 26 + 1
'' divide by 26
Let n = Int(n / 26)
'' correct for negative numbers
If digit < 0 Then Let n = n + 1: Let digit = digit - 26
'' prepend char corresponding to the digit to out
Let out = Chr(64 + digit) & out
Wend
'' return out
Let Base26 = out
End Function
-696443266.1.3.6.10.15.21.28
べき*V3035567339896938984978971
ですか?