NumeracionTemporal.vb

  1. ' NumeracionTemporal.vb — ProInf.net — 2-mar-2012
  2. '
  3. ' Clases:
  4. ' NumeracionTemporal (shared)
  5. ' NumeracionTemporalEnLetras
  6. ' NumeracionTemporalEnCifras
  7. '
  8. ' Requisitos:
  9. ' La clase "CifrasEnLetras"
  10. '
  11. ' Enlaces:
  12. ' http://es.wikipedia.org/wiki/Sistemas_de_tiempo
  13. '
  14. ' Ejemplos:
  15. ' cinco días = 5
  16. ' cuatro meses, dos semanas y tres días = 4*30 + 2*7 + 3
  17. ' un semestre = 6*30
  18. ' dos años y un día = 2*365+1
  19. ' un lustro y tres meses = 2*5*365 + 3*30
  20. ' seis años = 6*365
  21. ' dos lustros = 2*5*365
  22. ' un decenio = 10*365
  23. ' tres milenios, dos lustros y tres años = (3*1000 + 2*5+3)*365
  24. '
  25.  
  26. '================================================
  27. ' NUMERACIÓN TEMPORAL (COMPARTIDO)
  28.  
  29. Public Class NumeracionTemporal
  30.  
  31. Private Shared _enLetras As NumeracionTemporalEnLetras = Nothing
  32. Private Shared _enCifras As NumeracionTemporalEnCifras = Nothing
  33.  
  34. Public Shared Function ObtenerEnLetras(ByVal numero As Decimal) As String
  35. If _enLetras Is Nothing Then _enLetras = New NumeracionTemporalEnLetras()
  36. Return _enletras.Obtener(numero)
  37. End Function
  38.  
  39. Public Shared Function ObtenerEnCifras(ByVal numero As Decimal) As String
  40. If _enCifras Is Nothing Then _enCifras = New NumeracionTemporalEnCifras()
  41. Return _enCifras.Obtener(numero)
  42. End Function
  43.  
  44. End Class
  45.  
  46. '================================================
  47. ' NUMERACIÓN TEMPORAL EN LETRAS
  48.  
  49. Public Class NumeracionTemporalEnLetras
  50.  
  51. '--------------------------------------------
  52. ' INTERFAZ
  53.  
  54. Public Function Obtener(ByVal numero As Decimal) As String
  55. Dim tiemposAños = ObtenerTiempo(numero \ 365, unidades_años, factores_años)
  56. Dim tiemposDias = ObtenerTiempo(numero Mod 365, unidades_dias, factores_dias)
  57. Dim texto = Unir(tiemposAños, tiemposDias, ", ")
  58. texto = ObtenerAbreviaturas().Reemplazar(texto)
  59. texto = InsertarConjuncion(texto)
  60. Return texto
  61. End Function
  62.  
  63. Protected Function Unir(
  64. ByVal array1 As String(),
  65. ByVal array2 As String(),
  66. ByVal separador As String
  67. ) As String
  68. Dim union As IEnumerable(Of String) = array1.Union(array2)
  69. Dim lista As New List(Of String)
  70. For Each elemento In union
  71. lista.Add(elemento)
  72. Next
  73. Return Join(lista.ToArray(), separador)
  74. End Function
  75.  
  76. Protected Function InsertarConjuncion(ByVal texto As String) As String
  77. Dim posicion = texto.LastIndexOf(", ")
  78. If posicion > 0 Then
  79. texto = texto.Remove(posicion, 2).Insert(posicion, " y ")
  80. End If
  81. Return texto
  82. End Function
  83.  
  84. '--------------------------------------------
  85. ' IMPLEMENTACIÓN
  86.  
  87. Shared unidades_dias As String() = {"día", "semana", "mes", "año"}
  88. Shared factores_dias As Integer() = {1, 7, 30, 365}
  89.  
  90. Shared unidades_años As String() = {"año", "lustro", "década", "siglo", "milenio", "cron"}
  91. Shared factores_años As Integer() = {1, 5, 10, 100, 1000, 1000000}
  92.  
  93. Protected Function ObtenerTiempo(
  94. ByVal numero As Decimal,
  95. ByVal unidades As String(),
  96. ByVal factores As Integer()
  97. ) As String()
  98. Dim resultado As New List(Of String)
  99. For indice = unidades.Length - 1 To 0 Step -1
  100. Dim factor = numero \ factores(indice)
  101. numero = numero Mod factores(indice)
  102. If factor > 0 Then
  103. Dim unidad = unidades(indice)
  104. resultado.Add(ObtenerCantidad(factor, unidad))
  105. End If
  106. Next
  107. Return resultado.ToArray()
  108. End Function
  109.  
  110. '--------------------------------------------
  111. ' UTILIDADES
  112.  
  113. Protected Overridable Function ObtenerCantidad(
  114. ByVal cantidad As Integer,
  115. ByVal unidad As String
  116. ) As String
  117. Dim resultado As String
  118. Dim cifras = ObtenerCifras(cantidad, EsFemenino(unidad))
  119. If cantidad = 1 Then
  120. resultado = cifras & " " & unidad
  121. Else
  122. resultado = cifras & " " & EnPlural(unidad)
  123. End If
  124. Return resultado
  125. End Function
  126.  
  127. Protected Function ObtenerCifras(
  128. ByVal cantidad As Integer,
  129. ByVal enFemenino As Boolean
  130. ) As String
  131. If enFemenino Then
  132. Return CifrasEnLetras.convertirCifrasEnLetrasFemeninas(cantidad)
  133. Else
  134. Return CifrasEnLetras.convertirCifrasEnLetras(cantidad)
  135. End If
  136. End Function
  137.  
  138. Protected Function EsFemenino(ByVal unidad As String) As Integer
  139. Return unidad = "semana" Or unidad = "década"
  140. End Function
  141.  
  142. Protected Function EnPlural(ByVal texto As String) As String
  143. If AcabaEnVocal(texto) Then
  144. Return texto & "s"
  145. Else
  146. Return texto & "es"
  147. End If
  148. End Function
  149.  
  150. Protected Function AcabaEnVocal(ByVal texto As String) As String
  151. Return "aeiou".Contains(texto(texto.Length - 1))
  152. End Function
  153.  
  154. '--------------------------------------------
  155. ' ABREVIATURAS
  156.  
  157. Private Shared _abreviaturas As AbreviaturasEnLetras = Nothing
  158.  
  159. Protected Overridable Function ObtenerAbreviaturas() As AbreviaturasEnLetras
  160. If _abreviaturas Is Nothing Then
  161. _abreviaturas = New AbreviaturasEnLetras()
  162. End If
  163. Return _abreviaturas
  164. End Function
  165.  
  166. Protected Class AbreviaturasEnLetras
  167. Inherits Dictionary(Of String, String)
  168. Public Sub New()
  169. Add("dos semanas, un día", "una quincena")
  170. Add("dos meses", "un bimestre")
  171. Add("tres meses", "un trimestre")
  172. Add("cuatro meses", "un cuatrimestre")
  173. Add("seis meses", "un semestre")
  174. Add("dos años", "un bienio")
  175. Add("tres años", "un trienio")
  176. End Sub
  177. Public Function Reemplazar(ByVal texto As String) As String
  178. Dim enumerador As IDictionaryEnumerator = Me.GetEnumerator()
  179. Do While enumerador.MoveNext()
  180. texto = texto.Replace(enumerador.Key, enumerador.Value)
  181. Loop
  182. Return texto
  183. End Function
  184. End Class
  185.  
  186. End Class
  187.  
  188. '================================================
  189. ' NUMERACIÓN TEMPORAL EN CIFRAS
  190.  
  191. Public Class NumeracionTemporalEnCifras
  192. Inherits NumeracionTemporalEnLetras
  193.  
  194. Protected Overrides Function ObtenerCantidad(
  195. ByVal cantidad As Integer,
  196. ByVal unidad As String
  197. ) As String
  198. If cantidad = 1 Then
  199. Return cantidad & " " & unidad
  200. Else
  201. Return cantidad & " " & EnPlural(unidad)
  202. End If
  203. End Function
  204.  
  205. '--------------------------------------------
  206. ' ABREVIATURAS
  207.  
  208. Private Shared _abreviaturas As AbreviaturasEnCifras = Nothing
  209.  
  210. Protected Overrides Function ObtenerAbreviaturas() As AbreviaturasEnLetras
  211. If _abreviaturas Is Nothing Then
  212. _abreviaturas = New AbreviaturasEnCifras()
  213. End If
  214. Return _abreviaturas
  215. End Function
  216.  
  217. Protected Class AbreviaturasEnCifras
  218. Inherits AbreviaturasEnLetras
  219. Public Sub New()
  220. Add("2 semanas, 1 día", "1 quincena")
  221. Add("2 meses", "1 bimestre")
  222. Add("3 meses", "1 trimestre")
  223. Add("4 meses", "1 cuatrimestre")
  224. Add("6 meses", "1 semestre")
  225. Add("2 años", "1 bienio")
  226. Add("3 años", "1 trienio")
  227. End Sub
  228. End Class
  229.  
  230. End Class

Proinf.net